技术开发 频道

.NET 3.5中WCF客户端代理性能改进实战

  改进

  改进ClientBase性能的思路很简单:对ChannelFactory对象进行缓存。这与ASMX代理中的客户端类型缓存类似。

  为ClientBase进行的ChannelFactory缓存。

  核心思想是在AppDomain层缓存ChannelFactory对象, 这样一个ChannelFactory对象的生存时间就不由代理控制了。缓存是一种最常使用(most recently used, MRU)缓存。缓存大小被硬编码为32以便于将最少使用的ChannelFactory对象从缓存中移出。

  由于有了ChannelFactory 缓存,创建一个ClientBase对象的粗略过程如下:

  ①在ClientBase构造函数中,会有一个lookup 方法在缓存中寻找一个匹配的ChannelFactory.

  ② 如果找到了,对这个ChannelFactory的引用数量会加1. 否则,会基于设置新创建一个ChannelFactory.

  ③ 在ClientBase的内部信道(传输代理)创建之前,如果其他公共属性(比如ChannelFactory, Endpoint和ClientCredentials)被访问过,那么当前ClientBase的缓存逻辑会被禁用。

  ④ 一旦内部信道被成功创建且ClientBase的ChannelFactory对象没有被从缓存中去除而且缓存没有被禁用,ChannelFactory对象会被添加到缓存中。

  什么是匹配的ChannelFactory?

  我之前说过”匹配的“ChannelFactory了吗?是的,你得保证你可以基于ClientBase构造函数中的输入设置来区分不同的ChannelFactory对象。有两种类型构造函数:将绑定作为参数的和不将绑定作为参数的。这里是那些不将绑定作为参数的:

ClientBase();
ClientBase(
string endpointConfigurationName);
ClientBase(
string endpointConfigurationName, string remoteAddress);
ClientBase(
string endpointConfigurationName, EndpointAddress remoteAddress);
ClientBase(InstanceContext callbackInstance);
ClientBase(InstanceContext callbackInstance,
string endpointConfigurationName);
ClientBase(InstanceContext callbackInstance,
string endpointConfigurationName, string remoteAddress);
ClientBase(InstanceContext callbackInstance,
string endpointConfigurationName, EndpointAddress remoteAddress);

   对这些构造函数来说,所有的参数(包括默认的那个)都在下面列表中:

InstanceContext callbackInstance
string endpointConfigurationName
EndpointAddress remoteAddress

   只要在构造ClientBase的时候这些参数是一样的,我们可以完全假设会使用同样的ChannelFactory。幸运的是,String和EndpointAddress类型是不变的, 比如,我们可以做些简单的比较来确定这两个参数是否一样。对InstanceContext来说,我们可以使用对象引用比较。EndpointTrait类型作为MRU缓存的键。

  这里是以绑定作为参数的两个构造函数:

ClientBase(Binding binding, EndpointAddress remoteAddress);
ClientBase(InstanceContext callbackInstance, Binding binding, EndpointAddress remoteAddress);

  既然绑定对象是不变的,比如,人们可以在一个代理上使用它,然后修改一下并在另外一个代理上使用,我们可以很容易地检查一个绑定对象是否有改动。因此当绑定被提供给构造函数时,对应代理的缓存机制被禁用。

0
相关文章