為什麼第一個 WCF 客戶端呼叫很慢?
我試圖弄清楚為什麼客戶端應用程序啟動後的第一個 WCF 呼叫與第二個相比需要更多的時間。
我做了什麼來測試:
- 實現了簡單的自託管 WCF 伺服器和控制台客戶端。
- 伺服器已預熱- 我在執行測試之前執行它並多次呼叫方法。
- 綁定是
basicHttpBinding為了減少網路和安全成本。- 測試場景 - 啟動控制台客戶端應用程序,連續進行兩個相同的 WCF 服務呼叫。
在我的測試中,我看到第一次呼叫約 700 毫秒,第二次呼叫約 3 毫秒。
對於 JIT 編譯器來說,幾乎一秒鐘的時間似乎太多了。如果將這段時間用於初始化一些複雜的基礎架構
ObjectContext,例如 Entity Framework,我會接受,但我的程式碼非常簡單並且代理類已經編譯。我也試過
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>
通常第一次呼叫會花費更多時間,因為在該呼叫
Channel Factory中實例化並準備好進行通信,這會花費時間。創建的Channel Factory將被記憶體並在後續呼叫中重用,因此時間會更少。<http://social.msdn.microsoft.com/Forums/en/wcf/thread/43f89088-546b-46b0-adf8-214deb1741bd>
如果您呼叫 WCF 服務的頻率低於 15 秒(我們觀察到在我們的應用程序中需要等待大約 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