1. 程式人生 > >等到花兒也謝了的await

等到花兒也謝了的await

action stat mvc tor lba dem esp method net開發

async/task/await三組合是.NET Framework 4.5帶給.NET開發者的大禮,合理地使用它,可以提高應用程序的吞吐能力。

但是它的使用有點繞人,如果不正確使用,會帶來意想不到的問題——比如await之後一直在等待,等到花兒也謝了,也等不來。

這篇博文將向你展示我們在實際開發中遇到的這個問題。

先看一段ASP.NET MVC示例代碼:

技術分享
public class BlogController : Controller
{
    public async Task<ActionResult> AwaitDemo()
    {
        var responseHtml = GetResponseHtml("http://www.cnblogs.com/");
        return Content(responseHtml);
    }

    private string GetResponseHtml(string url)
    {
        return GetResponseContentAsync(url).Result;
    }

    private async Task<string> GetResponseContentAsync(string url)
    {
        var httpClient = new System.Net.Http.HttpClient();
        var response = await httpClient.GetAsync(url);
        if (response.StatusCode == System.Net.HttpStatusCode.OK)
        {
            return await response.Content.ReadAsStringAsync();
        }
        else
        {
            return "error";
        }
    }
}
技術分享

代碼說明:

  • 在上面的代碼中,雖然在Action方法之前加了async Task<ActionResult>,但由於在方法體中沒有使用await,所以實際還是以同步的方式執行的,與直接使用ActionResult是一樣的。
  • GetResponseHtml是同步方法,GetResponseContentAsync是異步方法,在GetResponseHtml中調用了異步的GetResponseContentAsync。(如果調用的是第三方程序集,我們就不知道在GetResponseHtml中進行了異步調用,所以這個方法的設計是有問題的)

這段代碼執行結果會是怎樣呢?

——結果就是沒有結果,一直在執行。。。

(註:如果在控制臺應用程序中調用同樣的GetResponseHtml,不會出現這個問題)

那如果解決這個問題呢:

解決方法一:在MVC Action中開啟一個Task進行await

技術分享
public async Task<ActionResult> AwaitDemo()
{
    var responseHtml = await Task.Factory.StartNew(() => 
        GetResponseHtml("http://www.cnblogs.com/"));
    return Content(responseHtml);
}
技術分享

解決方法二:將GetResponseHtml變成異步方法

技術分享
public async Task<ActionResult> AwaitDemo()
{
    var responseHtml = await GetResponseHtml("http://www.cnblogs.com/");
    return Content(responseHtml);
}

private async Task<string> GetResponseHtml(string url)
{
    return await GetResponseContentAsync(url);
}
技術分享

顯然,第2個解決方法是更好的。

所以,我們在設計一個方法(method)時,如果調用了async方法,一定要將這個方法本身設計為async的。不然,別人調用時很容易踩著這個坑,然後就一直等啊等。。。等到花兒謝了,電腦冒煙了,也等不到。

【相關鏈接】

等到花兒也謝了的await