文章出處

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的。不然,別人調用時很容易踩著這個坑,然后就一直等啊等。。。等到花兒謝了,電腦冒煙了,也等不到。

【相關鏈接】

async & await 的前世今生

Best Practices in Asynchronous Programming

Don't Block on Async Code

ASP.NET sync over async(異步中同步,什么鬼?)


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()