WCF中关于Client Proxy的一些总结

wcf的客户端需要通过代理来访问服务器发布的服务。
一、首先是建立一个代理类,根据binding的不同,可以继承System.ServiceModel.DuplexClientBase<T>或者System.ServiceModel.ClientBase<T>。 ClientBase<T> 是wcf中默认支持的,你可以使

用svcutil.exe工具来产生代理代码.
    MyContractClient proxy = new MyContractClient("MyEndpoint");
    proxy.MyMethod( );
    proxy.Close( );
二、直接利用ChannelFactory来生成代理
        Uri epAddress = new Uri("net.tcp://" + ipStr + ":9032/MyService");

        Binding bding = new NetTcpBinding("StreamedHTTP");
        factory = new ChannelFactory<IMyConstract>(bding, new EndpointAddress(epAddress));

        proxy = factory.CreateChannel();
它们之间的区别是
当使用方法1时,实际的调用过程是下面这样的:
- ChannelFactory.Create
- factory.CreateChannel
- ... use channel ...
- channel.Close
- factory.Close

在.net 3.0中,对于服务器和客户端来说,创建和销毁wcf代理代价非常昂贵。方法1在内部创建ChannelFactory<T>,每一个代理连接一个ChannelFactory对象,作为它的私有属性。ChannelFactory

的生存周期被代理控制。方法2要好一些,因为你可以自己控制ChannelFactory<T>对象。你可以仅仅创建一次,从而节省进一步创建代理的开销。
为什么创建和销毁代理花费的代价大,有以下几个方面的原因:
    1、构建契约描述树(ContractDescription tree)
    2、反射所有的CLR类型
    3、构建通道栈(channel stack)
    4、销毁所有的资源
在大多数情况下,这些数据是唯一的,尽管代理们使用同一种方式创建。
在.net 3.0(.net 3.5)中,ChannelFactory caching内含ClientBase<T>,这大大提高了方法1的效率。每一个被内部创建的通道都被增加到

System.ServiceModel.Channels.CommunicationObjectManager。因为其内部存储结构从List<T> 改变到 Hashtable,所以在.net 3.5中,方法1和方法2的性能都得到了提高。
总结:
    在大多数情况下,你可以重用代理,这个有最好的性能,尤其是你使用了安全特性。同时,在重用的时候,在你用代理之前,不用忘记显式打开(proxy.open())。
如果你用方法1,为了使ChannelFactory进行缓存,要注意以下两点:
 不用使用带有Binding参数的构造函数。
 不要访问代理的ChannelFactory,Endpoint和ClientCredentials属性。


在多线程环境下,重用代理需要注意以下两点:
    通道的上下文不允许多线程访问
    当使用single代理时,在通道中有一些瓶颈。

posted on 2010-02-26 16:22  oliverPP  阅读(2075)  评论(0编辑  收藏  举报

导航