Cache e fábrica de canal

Os aplicativos cliente do WCF usam a classe ChannelFactory<TChannel> para criar um canal de comunicação com um serviço WCF. Criar instâncias de ChannelFactory<TChannel> resulta em alguma sobrecarga porque envolve as seguintes operações:

  • Construir a árvore de ContractDescription

  • Refletir todos os tipos CLR necessários

  • Construir a pilha de canal

  • Descarte de recursos

Para ajudar a minimizar a sobrecarga, o WCF pode armazenar em cache fábricas de canal quando você está usando um proxy de cliente WCF.

Dica

Você tem controle direto sobre a criação da fábrica de canais quando usa a classe ChannelFactory<TChannel> diretamente.

Os proxies de cliente do WCF gerados com a Ferramenta de Utilitário de Metadados do ServiceModel (Svcutil.exe) são derivados de ClientBase<TChannel>. ClientBase<TChannel> define uma propriedade estática CacheSetting que define o comportamento de cache da fábrica de canais. As configurações de cache são feitas para um tipo específico. Por exemplo, a configuração de ClientBase<ITest>.CacheSettings como um dos valores definidos abaixo afetará apenas os proxies/ClientBase do tipo ITest. A configuração de cache para determinado ClientBase<TChannel> é imutável assim que a primeira instância de proxy/ClientBase é criada.

Como especificar o comportamento do cache

O comportamento do cache é especificado definindo a propriedade CacheSetting como um dos valores a seguir.

Valor da configuração do cache Descrição
AlwaysOn Todas as instâncias de ClientBase<TChannel> no domínio do aplicativo podem participar do cache. O desenvolvedor determinou que não há implicações adversas de segurança para o cache. O cache não será desativado mesmo se as propriedades "sensíveis à segurança" em ClientBase<TChannel> forem acessadas. As propriedades "sensíveis à segurança" de ClientBase<TChannel> são ClientCredentials, Endpoint e ChannelFactory.
Default Somente as instâncias de ClientBase<TChannel> criadas com base em pontos de extremidade definidos em arquivos de configuração participam do cache no domínio do aplicativo. Todas as instâncias de ClientBase<TChannel> criadas por meio de programação nesse domínio de aplicativo não participarão do cache. Além disso, o cache será desabilitado para uma instância de ClientBase<TChannel> uma vez que uma das propriedades "sensíveis à segurança" seja acessada.
AlwaysOff O cache está desativado para todas as instâncias de ClientBase<TChannel> de um tipo específico no domínio do aplicativo em questão.

Os snippets de código a seguir descrevem como usar a propriedade 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 { }

No código acima, todas as instâncias de TestClient usarão a mesma fábrica de canais.

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 {}

No exemplo acima, todas as instâncias de TestClient usarão a mesma fábrica de canais, exceto a instância nº 4. A instância nº 4 usará uma fábrica de canais criada especificamente para o uso dela. Essa configuração funcionará para cenários em que um ponto de extremidade específico precisa ter configurações de segurança diferentes dos outros pontos de extremidade do mesmo tipo de fábrica de canais (nesse caso, 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 {}

No exemplo acima, todas as instâncias de TestClient usarão diferentes fábricas de canais. Isso é útil quando cada ponto de extremidade tem requisitos de segurança diferentes e não faz sentido armazená-los em cache.

Confira também