2017-08-12 57 views
-1

我計算出我的C#web API的性能。我寫了一個非常簡單的HelloWorld響應:異步長操作與HttpResponseMessage

public class HelloWorldController : ApiController 
{ 
    public HttpResponseMessage Get() 
    { 

     return new HttpResponseMessage() 
     { 
      Content = new StringContent("HelloWorld") 
     }; 
    } 
} 

我通過使用JMeter我組1000級的用戶請求測試它完美地工作(CPU使用率高達100%)。但問題是,當api的運行時間稍長時,響應會變得更糟,每個響應只有3個響應(CPU使用率爲< 7%)。它爲1000個用戶請求花了小費。

public HttpResponseMessage Get() 
    { 
     Thread.Sleep(1000); 
     return new HttpResponseMessage() 
     { 
      Content = new StringContent("HelloWorld") 
     }; 
    } 

谷歌後,我想出了使用異步的想法,但我仍然有同樣的問題。我不知道問題是什麼或者我的代碼實現。以下是我的示例實現。

public async Task<HttpResponseMessage> Get() 
    { 
     return new HttpResponseMessage() 
     { 
      Content = new StringContent(await LongOperationAsync()) 
     }; 
    } 
    private string LongOperation() 
    { 
     //long operation here 
     Thread.Sleep(1000); 
     return "HelloWorld"; 
    } 

    private Task<string> LongOperationAsync() 
    { 
     return Task.Factory.StartNew(() => LongOperation()); 
    } 

任何人都知道什麼是問題或有關這個問題的任何想法?

+2

你認爲'Thread.Sleep(1000);'實際上在這裏做什麼? – DavidG

回答

3

的方法LongOperationAsync而LongOperation也應該是異步

private async Task<string> LongOperation() 
{ 
    //long operation here 
    await Task.Delay(1000); 
    return "HelloWorld"; 
} 
private async Task<string> LongOperationAsync() 
{ 
    var rt = await Task.Run(() => LongOperation()); 
    return rt; 
} 

見: Asynchronous programming

4

asyncawait不是靈丹妙藥,只是 「麥德codez moah awesomz」。 On ASP.NET, await enables your application to be more scalable (and respond to changes in scale more quickly) by making optimum use of the thread pool。所以,如果你釋放一個線程池線程(await),但使用另一個線程池線程(StartNew),你不會獲得任何東西。特別是,exposing a fake-async method for a synchronous API is an antipattern

如果可能的話,最好的辦法是讓LongOperationAsync一個自然的異步操作:

public async Task<HttpResponseMessage> Get() 
{ 
    return new HttpResponseMessage() 
    { 
    Content = new StringContent(await LongOperationAsync()) 
    }; 
} 

private async Task<string> LongOperationAsync() 
{ 
    //long operation here 
    await Task.Delay(1000); 
    return "HelloWorld"; 
} 

如果這是不可能的,那麼你可能也保持同步。使用Task.Run(或even worse,StartNew)根本沒有幫助。