Производство каналов и кэширование

Клиентские приложения WCF используют класс ChannelFactory<TChannel> для создания коммуникационного канала со службой WCF. Создание экземпляров класса ChannelFactory<TChannel> оказывает определенное влияние на производительность, поскольку выполняются следующие операции:

  • Построение дерева ContractDescription

  • Отображение всех необходимых типов CLR

  • Построение стека каналов

  • Освобождение ресурсов

Чтобы уменьшить дополнительные расходы ресурсов, WCF может кэшировать фабрики каналов при использовании прокси клиента WCF.

Совет

Вы непосредственно управляете созданием фабрики каналов, когда класс ChannelFactory<TChannel> используется напрямую.

Клиентские прокси-серверы WCF, созданные с помощью программы служебной программы метаданных ServiceModel (Svcutil.exe), являются производными от ClientBase<TChannel>. ClientBase<TChannel> определяет статическое свойство CacheSetting, которое определяет режим кэширования фабрики каналов. Параметры кэша задаются для определенного типа. Например, параметр ClientBase<ITest>.CacheSettings для одного из значений, определенных ниже, влияет только на прокси-сервер или КлиентБазу типа ITest. Параметры кэша для конкретного ClientBase<TChannel> являются неизменяемыми после создания первого экземпляра класса-посредника или ClientBase.

Установка режима кэширования

Режим кэширования задается установкой свойства CacheSetting в одно из следующих значений.

Значение параметра кэша Description
AlwaysOn Все экземпляры ClientBase<TChannel> в пределах домена приложения могут участвовать в кэшировании. Разработчик определил, что при кэшировании не будет неблагоприятных последствий для безопасности. Кэширование не отключается, даже если доступ к свойствам ClientBase<TChannel> безопасности не учитывается. Свойства ClientBase<TChannel> "с учетом безопасности", а ClientCredentialsEndpointChannelFactoryтакже .
Default Только экземпляры ClientBase<TChannel>, созданные на основе конечных точек, определенных в файлах конфигурации, участвуют в кэшировании внутри домена приложения. Ни один экземпляр ClientBase<TChannel>, созданный программно внутри домена приложения, не будет участвовать в кэшировании. Кроме того, кэширование будет отключено для экземпляра ClientBase<TChannel> одного из его свойств с учетом безопасности.
AlwaysOff Кэширование отключается для всех экземпляров ClientBase<TChannel> определенного типа в пределах домена приложений.

Следующие фрагменты кода показывают использование свойства CacheSetting.

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 будут использовать одну и ту же фабрику каналов.

class Program
{
   static void Main(string[] args)
   {
      ClientBase<ITest>.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. Экземпляр № 4 будет использовать фабрику каналов, созданную специально для этой цели. Этот параметр не работает в сценариях, где определенной конечной точке необходимы различные параметры безопасности из других конечных точек того же типа фабрики каналов (в данном случае ITest).

class Program
{
   static void Main(string[] args)
   {
      ClientBase<ITest>.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 будут использовать различные фабрики каналов. Это полезно в случае, если каждая конечная точка имеет различные требования к безопасности и нет смысла выполнять кэширование.

См. также