我是伊只雄熊

导航

异步多线程 ASP.NET 同步调用异步 使用Result产生死锁

  一个方法调用了async方法,要将这个方法本身设计为async。

public class BlogController : Controller
{
    public async Task<ActionResult> AwaitDemo()
    {
      //虽然写了async,但是没有await,所以还是同步
var responseHtml = GetResponseHtml("http://www.cnblogs.com/"); return Content(responseHtml); }
     //同步方法
private string GetResponseHtml(string url) {
     //调用了异步方法,而且用Result获取返回值
return GetResponseContentAsync(url).Result; }
  //异步方法 async/await
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"; } } }

  运行程序,一致卡死,而在控制台应用程序中调用同样的GetResponseHtml,不会出现问题,因为控制台没有同步上下文SynchronizationContext

,而ASP.NET程序有同步上下文AspNetSynchronizationContext,异步执行完后,找到前边的AspNetSynchronizationContext。

  改造方法:

  1、开启Task,进行await

  GetResponseHtml方法还是同步,而AwaitDemo,变成了异步

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

  2、将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);
}

 

posted on 2018-02-08 17:34  我是伊只雄熊  阅读(390)  评论(0编辑  收藏  举报