¿Por qué la primera llamada del cliente WCF es lenta?

Estoy tratando de averiguar por qué la primera llamada WCF después del inicio de la aplicación cliente toma mucho más tiempo en comparación con la segunda.

Lo que hice para probar eso:

  1. Implementado un servidor WCF alojado y un cliente de consola.
  2. El servidor se calienta – Lo ejecuto y llamo al método varias veces antes de ejecutar la prueba.
  3. La vinculación es basicHttpBinding para reducir los gastos generales de seguridad y de red.
  4. Escenario de prueba: inicie la aplicación del cliente de la consola, haciendo dos llamadas al servicio WCF idénticas en una fila.

En mis pruebas veo ~ 700 milisegundos para la primera llamada y ~ 3 milisegundos para la segunda llamada.

Casi un segundo parece ser demasiado tiempo para el comstackdor JIT. Lo aceptaría si ese tiempo se usa para inicializar alguna infraestructura complicada como ObjectContext en Entity Framework, pero mi código es muy simple y las clases de proxy ya están comstackdas.

También probé el enlace netNamedPipeBinding . El resultado prueba el patrón: la primera llamada tarda ~ 800 ms, la segunda llamada demora ~ 8 ms.

Apreciaría si alguien puede explicar por qué la primera llamada de servicio lleva mucho tiempo.

Probado en Win 7 64 bit.

Mi implementación está abajo.

Contrato:

 [ServiceContract] public interface ICounter { [OperationContract] int Add(int num); } 

Implementación del servicio:

 public class CounterService: ICounter { private int _value = 0; public int Add(int num) { _value += num; Console.WriteLine("Method Add called with argument {0}. Method returned {1}", num, _value); return _value; } } 

Implementación del servidor:

 class Program { static void Main(string[] args) { Uri baseAddress = new Uri("http://localhost:8080/Service"); // Create the ServiceHost. using (ServiceHost host = new ServiceHost(typeof(CounterService), baseAddress)) { host.Open(); Console.WriteLine("The service is ready at {0}", baseAddress); Console.WriteLine("Press  to stop the service."); Console.ReadLine(); // Close the ServiceHost. host.Close(); } } } 

Configuración del servidor:

                    

Implementación del cliente ( CounterProxy se genera a partir de la referencia del servicio):

 Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); using (var proxy = new CounterProxy.CounterClient(_endpointConfigurationName)) { output = proxy.Add(1); } stopWatch.Stop(); // Get the elapsed time as a TimeSpan value. TimeSpan ts = stopWatch.Elapsed; 

Función que contiene ese código llamado dos veces seguidas.

Configuración del cliente:

         

Por lo general, la primera llamada lleva más tiempo porque en esa llamada Channel Factory se crea una instancia y se prepara para la comunicación y eso le cuesta tiempo. La Channel Factory creada se almacenará en caché y se reutilizará en llamadas posteriores, por lo que el tiempo será menor.

http://social.msdn.microsoft.com/Forums/en/wcf/thread/43f89088-546b-46b0-adf8-214deb1741bd

Tengo un problema similar. Entonces, lo que realmente hicimos, escribimos un servicio que invoca el servicio WCF por algún intervalo. Sé que no es una solución elegante, pero está funcionando.

Si realiza llamadas a su servicio WCF con una frecuencia inferior a 15 segundos (observamos la necesidad de esperar unos 20 segundos en nuestra aplicación), este blog de Microsoft parece explicar su problema: http://blogs.msdn.com/b/wenlong /archive/2010/02/11/why-does-wcf-become-slow-after-being-idle-for-15-seconds.aspx

El artículo también vincula a esta entrada que menciona una solución para SetMinThreads () que también parece ser un problema que contribuye: http://blogs.msdn.com/b/wenlong/archive/2010/02/11/why-are- wcf-responses-slow-and-setminthreads-does-not-work.aspx

Estaba viendo retrasos en el rango de 30 segundos cuando estaba creando mi instancia de proxy de servicio que sabía que debía estar relacionada con algún tipo de tiempo de espera de red.

Al final, para mí fue en realidad verificaciones de la Lista de revocación de certificados que estaban siendo bloqueadas o frustradas por el proxy corporativo (yay Websense) como se destaca aquí: ¿el arranque del servicio WCF es demasiado lento? ¿Has pensado en verificar CRL? .

Para referencia futura y en caso de que el enlace se agote, se redujo a agregar lo siguiente a la configuración del cliente: