首页 > 解决方案 > HttpWebResponse.GetResponseAsync 死锁

问题描述

我有一个简单的 Asp.Net MVC 控制器 (.NET 4.7.2) 和产生多个异步 http 请求的简单方法。

using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace WebApplication1.Controllers
{
  public class HomeController : Controller
  {
    public async Task<string> Index()
    {
      var tasks = Enumerable.Range(0, N).Select(MakeHttpCall);
      await Task.WhenAll(tasks);
      return "done";
    }

    private static async Task MakeHttpCall(int i)
    {
      Console.WriteLine("Start "+i);
      await GetUrlAsync(URL);
      Console.WriteLine("Finish "+i);
    }

    public static async Task GetUrlAsync(string url)
    {
      var request = WebRequest.Create(url);
      request.Method = "GET";

      using (var response = (HttpWebResponse) await request.GetResponseAsync())
      using (var streamReader = new StreamReader(response.GetResponseStream()))
      {
        streamReader.ReadToEnd();
      }
    }
  }
}

如果 N = 20 一切都按预期工作。但是如果 N = 100(在我的情况下)它将导致死锁并且索引操作将挂起。

为什么会这样?

Ps 这个问题不会在控制台应用程序中重现。所以它可能与本文中描述的 asp.net 同步上下文有关

https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

await request.GetResponseAsync().ConfigureAwait(false)解决问题,但不回答主要问题。是因为方法 GetResponseAsync() 不是“真正的异步”吗?可能有人可以澄清一下...

标签: c#.netasp.net-mvc

解决方案


推荐阅读