2012-06-02 52 views
13

我想弄清楚爲什麼客戶端應用程序啓動後的第一個WCF調用需要比第二個更多的時間。爲什麼第一個WCF客戶端調用較慢?

我做了什麼測試:

  1. 實現簡單的自承載的WCF服務器和控制檯客戶端。
  2. 服務器被預熱 - 我運行它並在運行測試前多次調用方法。
  3. 綁定爲basicHttpBinding以減少網絡和安全開銷。
  4. 測試場景 - 啓動控制檯客戶端應用程序,在一行中創建兩個完全相同的WCF服務調用。

在我的測試中,我看到〜700毫秒的第一次通話和~3毫秒的第二次通話。

對於JIT編譯器來說,差不多一秒的時間似乎太多了。如果這段時間用於初始化Entity Framework中的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> 
+0

可能加載/編譯代理對象第一次,在XML序列化器等,如果您看看輸出窗口,你應該看到類似於「Loaded assembly x54fjfj3fj」這是一個已編譯的WCF客戶端。 –

+0

我責怪安全檢查和另外100個未知數。涉及的二進制文件比部署服務中涉及的要多。要在配置和訪問日誌中調試服務使用跟蹤器,他們將以毫秒爲單位顯示花費在什麼時間上的步驟。即使您的所有內容都是匿名的,您仍然可以看到身份驗證,過濾器等內容。 – 2012-06-02 04:46:50

回答

7

通常第一次通話需要更多時間,因爲在那次通話中,Channel Factory被實例化並準備就緒以進行通信並且花費時間。創建的Channel Factory將在隨後的調用中被緩存和重用,所以時間會更短。

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

+0

但是,如果我理解正確,這個建議是針對客戶端的。我們不能在服務方面做任何事情。要說每個客戶都這麼做並不容易。 – batmaci

+0

看起來像微軟終於對此有所控制:https://msdn.microsoft.com/en-us/library/hh160401%28v=vs.110%29.aspx – userx

2

我有類似的問題。因此,我們實際上做了什麼,我們編寫了每隔一定時間間隔調用WCF服務 的服務。我知道這不是一個優雅的解決方案,但它的工作。

+0

你有什麼想法爲什麼發生?似乎很多人看到它,但我不知道誰知道原因。感謝您的迴應。 –

+1

看看這個,寫得很好http://www.codeproject.com/Tips/114132/WCF-First-Call-Slow – GutterStink

+0

你用了什麼間隔?從我所知道的情況來看,緩存似乎並沒有與超時掛鉤。但不到1分鐘。 – userx

2

如果您正在爲您的WCF服務調用次數少於15秒(我們觀察到需要等待在我們的應用程序大約20秒),這個微軟的博客上解釋你的問題: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

2

我看到在30秒範圍內的延遲,當我第一次創建我SER我知道的副代理實例必須與某種網絡超時有關。

最後對我來說,它實際上是檢查證書吊銷列表,被公司代理(yay Websense)阻止或沮喪,如下所示:WCF service startup too slow? Have you thought to CRL check?

以供將來參考,並在情況下,鏈接去死它來到了添加以下的客戶端配置:

<configuration> 
    <runtime> 
    <generatePublisherEvidence enabled=「false」/> 
    </runtime> 
</configuration> 
+2

在.NET Framework 4和更高版本中,這元素對裝配加載時間沒有影響。有關詳細信息,請參閱.NET Framework中安全更改中的「安全策略簡化」部分.https://msdn.microsoft.com/en-us/library/dd233103(v = vs.100).aspx(switch to .NET 4.0) – Ludwo