2011-11-01 22 views
1

我寫了下面的WCF服務,它實現了兩種方法。他們都做同樣的事情,但其中一個是同步的,另一個是異步的。負載測試的結果(使用Pylot)令人失望。我從該方法的同步和異步版本獲得幾乎相同的吞吐量(請參見下面的性能數字)。WCF - AsyncPattern性能

我在真正的IIS站點(不是卡西尼)部署了服務,我看到了相同的模式。我究竟做錯了什麼?我的印象是,使用WCF AsyncPattern我將能夠增加負載。我的假設是否正確?難道我做錯了什麼?

謝謝!

[ServiceContract] 
public class Service1 
{ 
    // Synchronous version 
    [WebGet(UriTemplate = "/sync")] 
    public List<SampleItem> GetSamples() 
    { 
     return this.LongRunningMethod(); 
    } 

    // Asynchronous version - Begin 
    [WebGet(UriTemplate = "/async")] 
    [OperationContract(AsyncPattern = true)] 
    public IAsyncResult BeginGetSampleAsync(AsyncCallback callback, object state) 
    { 
     var task = Task<List<SampleItem>>.Factory.StartNew(() => this.LongRunningMethod()); 

     Func<List<SampleItem>> getSampleItems =() => this.LongRunningMethod(); 

     return getSampleItems.BeginInvoke(callback, state); 
    } 

    // Asynchronous version - End 
    public List<SampleItem> EndGetSampleAsync(IAsyncResult result) 
    { 
     AsyncResult typedAsyncResult = (AsyncResult)result; 
     Func<List<SampleItem>> func = (Func<List<SampleItem>>)typedAsyncResult.AsyncDelegate; 

     return func.EndInvoke(result); 
    } 

    private List<SampleItem> LongRunningMethod() 
    { 
     // Simulate some load... I/O operations 
     Thread.Sleep(500); 

     return new List<SampleItem>() { new SampleItem() { Id = 1, StringValue = "Hello" } }; 
    } 

下面是性能。數字。

Performance Numbers 
------------------------------------------------- 
Test parameters: 
    number of agents:   500 
    test duration in seconds: 60 
    rampup in seconds:   0 
    interval in milliseconds: 0 
    test case xml:    **syncTestCase.xml** 
    log messages:    False 


Started agent 500 

All agents running... 


[################100%##################] 60s/60s 

Requests: 3836 
Errors: 0 
Avg Response Time: 7.286 
Avg Throughput: 63.92 
Current Throughput: 70 
Bytes Received: 852036 

------------------------------------------------- 

Test parameters: 
    number of agents:   500 
    test duration in seconds: 60 
    rampup in seconds:   0 
    interval in milliseconds: 0 
    test case xml:    **asyncTestCase.xml** 
    log messages:    False 


Started agent 500 

All agents running... 


[################100%##################] 60s/60s 

Requests: 3884 
Errors: 0 
Avg Response Time: 7.176 
Avg Throughput: 64.66 
Current Throughput: 620 
Bytes Received: 862248 

------------------------------------------------- 

回答

3

你的測試很人造。異步編程最適用於需要等待正在運行的線程的I/O限制操作(相反,它們應該基於IO-completion ports或類似)。您的測試使用線程池線程(BeginInvoke/EndInvoke)並阻止它們(Thread.Sleep),這幾乎可以保證您最終會在執行更差的時比在同步情況下不會吃掉任何額外的線程。

總之:不要使用服務器端異步,除非你在服務器端有I/O綁定的工作 - 如果你是CPU綁定的,堅持一個同步服務器實現(可能與一個MaxConcurrentCalls設置等於服務器上的CPU核心數量)。