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.¿Por qué es lenta la primera llamada de cliente WCF?
Lo que hice para probar que:
- Implementado simple auto organizadas WCF servidor y el cliente de consola.
- El servidor se calienta - Lo ejecuto y llamo al método varias veces antes de ejecutar la prueba.
- El enlace es
basicHttpBinding
para reducir los gastos generales de seguridad y de red. - 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 compilador 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 compiladas.
También intenté netNamedPipeBinding
encuadernación. El resultado prueba el patrón: la primera llamada tarda ~ 800 ms, la segunda llamada demora ~ 8 ms.
Agradeceré si alguien puede explicar por qué la primera llamada de servicio lleva tanto tiempo.
Probado en Win 7 64 bit.
Mi implementación está por debajo.
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;
}
}
Servidor de Aplicación:
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 <Enter> to stop the service.");
Console.ReadLine();
// Close the ServiceHost.
host.Close();
}
}
}
Configuración del servidor:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="Server.CounterService">
<endpoint address="base" binding="basicHttpBinding" name="baseDefault"
contract="Contract.ICounter" />
<endpoint address="net.pipe://localhost/Service/netNamedPipe"
binding="netNamedPipeBinding" name="netNamedPipeDefault" contract="Contract.ICounter" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
implementación del cliente (CounterProxy
se genera a partir referencia de 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 contenga ese código se llama dos veces en una fila.
de configuración del cliente:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<client>
<endpoint address="http://localhost:8080/Service/base" binding="basicHttpBinding"
contract="CounterProxy.ICounter"
name="baseDefault" />
</client>
</system.serviceModel>
</configuration>
Probablemente cargar/compilado el objeto proxy primera vez, los serializadores XML, etc Si usted mira la ventana de salida, deberías ver algo como "Loaded assembly x54fjfj3fj", que es un cliente compilado de WCF. –
Culpo a las comprobaciones de seguridad y otras 100 incógnitas. Hay mucho más binarios involucrados que lo que está en servicio desplegado. Para depurar los rastreadores de uso del servicio en los registros de configuración y visita, mostrarán los pasos en milisegundos en los que se gasta exactamente el tiempo. Verá algo así como Autenticación, filtros, etc. incluso si tiene todo actuando como anónimo. –