使用 Async Await 是否可以避免线程耗尽?

VSO*_*VSO 4 c# multithreading non-exhaustive-patterns asp.net-core-2.1

我们正在对端点上的以下性能问题进行故障排除.NET Core API

  1. 端点500MS在较小负载下始终返回小于。
  2. 当我们从 3 个浏览器访问端点时,每秒一个请求,它会逐渐变慢(在添加第三个浏览器进行调用后一分钟内,响应时间下降到50,000MS甚至更糟。
  3. 每个附加浏览器都会添加 API 使用的线程,例如 40 个线程基础,第二个浏览器命中端点导致 52 个线程,第三个峰值导致 70 个线程,依此类推。
  4. 当加载一个端点时,整个API(所有端点)返回缓慢。这是我思考“线程耗尽”的主要原因,以及第三点。

目前的代码如下所示:

    public IActionResult GetPresentationByEvent(int eventid)
    {
      return Authorized(authDto =>
      {
        var eventList = _eventService.GetPresentationByEvent(eventid);
        return Ok(eventList)
      })
    }
Run Code Online (Sandbox Code Playgroud)

我的理论是,return Authorized(authDto =>持有一个线程直到它返回,导致线程耗尽。

    public async Task<IActionResult> GetPresentationByEvent(int eventid)
    {
      return Authorized(async authDto =>
      {
        Task<List<whatever>> eventList = _eventService.GetPresentationByEvent(eventid);
        return Ok(eventList)
      }
    }
Run Code Online (Sandbox Code Playgroud)

Authorized是第三方库的一部分,所以我无法轻松测试它。想知道这是否是一个可能的问题/解决方案。

Bru*_*ndo 6

是的,异步等待可以减少线程耗尽。简而言之,当您生成的任务多于线程池可以处理的任务时,就会出现线程耗尽。

您可以在此处检查一些微妙的细节:线程饥饿和排队

您唯一需要记住的是,您永远不应该在任务中阻塞。这意味着使用 async wait 调用异步代码(并且永远不要在未完成的任务上使用 .Wait 或 .Result)。

如果您使用一些不使用异步等待模式的阻塞代码,则必须在专用线程(而不是任务线程队列)上生成它。