通道工厂和缓存Channel Factory and Caching

WCF 客户端应用程序使用 ChannelFactory<TChannel> 类来创建 WCF 服务的通信通道。WCF client applications use the ChannelFactory<TChannel> class to create a communication channel with a WCF service. 创建 ChannelFactory<TChannel> 实例会带来一定的开销,因为这涉及以下操作:Creating ChannelFactory<TChannel> instances incurs some overhead because it involves the following operations:

  • 构造 ContractDescriptionConstructing the ContractDescription tree

  • 反映所有所需的 CLR 类型Reflecting all of the required CLR types

  • 构造通道堆栈Constructing the channel stack

  • 资源的释放Disposing of resources

为了尽量减少这种开销,WCF 可以缓存使用 WCF 客户端代理时的通道工厂。To help minimize this overhead, WCF can cache channel factories when you are using a WCF client proxy.

提示

当直接使用 ChannelFactory<TChannel> 类时,您可以直接控制通道工厂创建。You have direct control over channel factory creation when you use the ChannelFactory<TChannel> class directly.

Svcutil.exe 元数据实用工具 ()生成的 WCF 客户端代理派生自ClientBase<TChannel>WCF client proxies generated with ServiceModel Metadata Utility Tool (Svcutil.exe) are derived from ClientBase<TChannel>. ClientBase<TChannel> 定义一个静态 CacheSetting 属性,该属性定义通道工厂缓存行为。ClientBase<TChannel> defines a static CacheSetting property that defines channel factory caching behavior. 为特定类型设定缓存设置。Cache settings are made for a specific type. 例如, 将设置ClientBase<ITest>.CacheSettings为下面定义的值之一将仅影响类型ITest为的代理/ClientBase。For example, setting ClientBase<ITest>.CacheSettings to one of the values defined below will affect only those proxy/ClientBase of type ITest. 特定 ClientBase<TChannel> 的缓存设置在创建第一个代理/ClientBase 实例后就不可改变。The cache setting for a particular ClientBase<TChannel> is immutable as soon as the first proxy/ClientBase instance is created.

指定缓存行为Specifying Caching Behavior

缓存行为通过将 CacheSetting 属性设置为下列值之一指定。Caching behavior is specified by setting the CacheSetting property to one of the following values.

缓存设置值Cache Setting Value 描述Description
AlwaysOn 应用程序域内的 ClientBase<TChannel> 的所有实例都可以参与缓存。All instances of ClientBase<TChannel> within the app-domain can participate in caching. 开发人员已经确定对缓存没有不利的安全性影响。The developer has determined that there are no adverse security implications to caching. 即使访问了上的ClientBase<TChannel> "安全敏感" 属性, 缓存也不会关闭。Caching will not be turned off even if "security-sensitive" properties on ClientBase<TChannel> are accessed. 的 "安全敏感" ClientBase<TChannel>属性是ClientCredentialsEndpointChannelFactoryThe "security-sensitive" properties of ClientBase<TChannel> are ClientCredentials, Endpoint and ChannelFactory.
Default 只有从在配置文件中定义的终结点创建的 ClientBase<TChannel> 的实例才参与应用程序域内的缓存。Only instances of ClientBase<TChannel> created from endpoints defined in configuration files participate in caching within the app-domain. 以编程方式在应用程序域内创建的 ClientBase<TChannel> 的任何实例都将不参与缓存。Any instances of ClientBase<TChannel> created programmatically within that app-domain will not participate in caching. 此外, ClientBase<TChannel>只要访问了其任何 "安全敏感" 属性, 就会对实例禁用缓存。Also, caching will be disabled for an instance of ClientBase<TChannel> once any of its "security-sensitive" properties is accessed.
AlwaysOff 在相关应用程序域内,已对特定类型的 ClientBase<TChannel> 的所有实例关闭缓存。Caching is turned off for all instances of ClientBase<TChannel> of a particular type within the app-domain in question.

下面的代码段演示如何使用 CacheSetting 属性。The following code snippets illustrate how to use the CacheSetting property.

class Program
{
   static void Main(string[] args)
   {
      ClientBase<ITest>.CacheSettings = CacheSettings.AlwaysOn;
      foreach (string msg in messages)
      {
         using (TestClient proxy = new TestClient (new BasicHttpBinding(), new EndpointAddress(address)))
         {
            // ...
            proxy.Test(msg);
            // ...
         }
      }
   }
}
// Generated by SvcUtil.exe
public partial class TestClient : System.ServiceModel.ClientBase, ITest { }

在上述代码中,TestClient 的所有实例都将使用相同的通道工厂。In the above code, all instances of TestClient will use the same channel factory.

class Program
{
   static void Main(string[] args)
   {
      ClientBase.CacheSettings = CacheSettings.Default;
      int i = 1;
      foreach (string msg in messages)
      {
         using (TestClient proxy = new TestClient ("MyEndpoint", new EndpointAddress(address)))
         {
            if (i == 4)
            {
               ServiceEndpoint endpoint = proxy.Endpoint;
               ... // use endpoint in some way
            }
            proxy.Test(msg);
         }
         i++;
   }
}

// Generated by SvcUtil.exe
public partial class TestClient : System.ServiceModel.ClientBase, ITest {}

在上述示例中,TestClient 的所有实例都将使用相同的通道工厂,实例 #4 除外。In the example above, all instances of TestClient would use the same channel factory except instance #4. 实例 # 4 将使用专门供其使用而创建的通道工厂。Instance #4 would use a channel factory that is created specifically for its use. 此设置适用于此类方案:特定终结点需要的安全设置不同于属于相同通道工厂类型(在此情况下为 ITest)的其他终结点。This setting would work for scenarios where a particular endpoint needs different security settings from the other endpoints of the same channel factory type (in this case ITest).

class Program
{
   static void Main(string[] args)
   {
      ClientBase.CacheSettings = CacheSettings.AlwaysOff;
      foreach (string msg in messages)
      {
         using (TestClient proxy = new TestClient ("MyEndpoint", new EndpointAddress(address)))
         {
            proxy.Test(msg);
         }
      }
   }
}

// Generated by SvcUtil.exe
public partial class TestClient : System.ServiceModel.ClientBase, ITest {}

在上面的示例中,TestClient 的所有实例将使用不同的通道工厂。In the example above, all instances of TestClient would use different channel factories. 当每个终结点具有不同的安全需求并且对缓存没有意义时,这非常有用。This is useful when each endpoint has different security requirements and it makes no sense to cache.

请参阅See also