我试图找出为什么客户端应用程序开始后的第一个WCF调用花费更多的时间与第二个。
我所做的测试是:
- 实现简单的自承载的WCF服务器和控制台客户端。
- 服务器是热身 -我运行它,并运行测试之前调用方法多次。
- 绑定是
basicHttpBinding
减少网络和安全的开销。 - 测试场景 - 启动控制台客户端应用程序,使得在连续两个相同的WCF服务电话。
在我的测试中,我看到〜700毫秒的第一个电话和〜3毫秒的第二个电话。
几乎是第二似乎是JIT编译器太多时间。 如果时间用于初始化像一些复杂的基础设施我会接受ObjectContext
实体框架,但我的代码是非常简单和代理类已经被编译。
我也试过netNamedPipeBinding
结合。 结果证明图案 - 第一呼叫发生〜800毫秒,第二呼叫花费〜8毫秒。
将不胜感激,如果任何人都可以解释为什么第一个服务调用花费这么多的时间。
测试在Win 7 64位。
我的实现如下。
合同:
[ServiceContract]
public interface ICounter
{
[OperationContract]
int Add(int num);
}
服务实现:
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;
}
}
服务器实现:
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();
}
}
}
服务器配置:
<?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>
客户端执行( CounterProxy
从服务引用生成):
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;
包含代码功能连续叫两次。
客户端配置:
<?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>