我试图弄清楚为什么客户端应用程序启动后第一次WCF调用与第二次调用相比要花费更多时间。
我做了什么测试:
basicHttpBinding
,以减少网络和安全开销。在我的测试中,我看到第一次通话约为700毫秒,第二次通话约为3毫秒。
几乎一秒似乎是JIT编译器的时间太多了。我会接受,如果那个时间用于初始化一些复杂的基础设施,如实体框架中的ObjectContext
,但我的代码非常简单,代理类已经编译。
我也试过netNamedPipeBinding
绑定。结果证明模式 - 第一次调用需要~800 ms,第二次调用需要~8 ms。
如果有人能解释为什么第一次服务电话花费这么多时间,我们将不胜感激。
在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>
答案 0 :(得分:7)
通常第一次调用需要更多时间,因为在该调用中Channel Factory
被实例化并准备好进行通信并且花费时间。创建的Channel Factory
将被缓存并在后续调用中重用,因此时间会更短。
http://social.msdn.microsoft.com/Forums/en/wcf/thread/43f89088-546b-46b0-adf8-214deb1741bd
答案 1 :(得分:2)
我有类似的问题。那么我们实际上做了什么,我们编写了调用WCF服务的服务 每隔一段时间。我知道这不是一个优雅的解决方案,但它正在发挥作用。
答案 2 :(得分:2)
如果您在15秒内不太频繁地拨打WCF服务(我们发现需要在我们的应用程序中等待大约20秒),这个Microsoft博客似乎可以解释您的问题:http://blogs.msdn.com/b/wenlong/archive/2010/02/11/why-does-wcf-become-slow-after-being-idle-for-15-seconds.aspx
该文章还链接到此条目,其中提到了对SetMinThreads()的修复,这似乎也是一个有问题的问题: http://blogs.msdn.com/b/wenlong/archive/2010/02/11/why-are-wcf-responses-slow-and-setminthreads-does-not-work.aspx
答案 3 :(得分:2)
当我第一次创建我的服务代理实例时,我看到了30秒范围内的延迟,我知道它必须与某种网络超时有关。
最后对我来说实际上是检查证书撤销列表被公司代理(yay Websense)阻止或挫败,如下所示:WCF service startup too slow? Have you thought to CRL check?。
供将来参考,如果链接失效,可以将以下内容添加到客户端配置中:
<configuration>
<runtime>
<generatePublisherEvidence enabled=“false”/>
</runtime>
</configuration>