async/task/await

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

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

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

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

複製代碼
複製代碼
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中進行了異步調用,因此這個方法的設計是有問題的)

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

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

(注:若是在控制檯應用程序中調用一樣的GetResponseHtml,不會出現這個問題)開發

那若是解決這個問題呢:同步

解決方法一:在MVC Action中開啓一個Task進行awaitstring

複製代碼
複製代碼
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的。否則,別人調用時很容易踩着這個坑,而後就一直等啊等。。。等到花兒謝了,電腦冒煙了,也等不到。

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息