使用异步等待是否可以避免线程耗尽? [英] Does Using Async Await Avoid Thread Exhaustion?

查看:71
本文介绍了使用异步等待是否可以避免线程耗尽?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We are troubleshooting the following performance issues on a .NET Core API endpoint:

  1. 端点在较小负载下持续返回的时间少于 500MS .
  2. 当我们通过3个浏览器访问端点时,每秒发出一个请求,它会变慢(在添加第三个浏览器进行通话的一分钟内,响应时间下降到 50,000MS或更糟.
  3. 每个其他浏览器添加API使用的线程,例如基本线程数为40,第二个浏览器命中端点将导致52个线程,第三个峰值为70,依此类推.
  4. 加载一个端点后,整个API会缓慢返回(所有端点).这是我与#3"一起思考线程耗尽"的主要原因.
  1. The endpoint consistently returns in less than 500MS under minor load.
  2. When we hit the endpoint from 3 browsers, with one request a second, it gets progressively slower (within a minute of adding a third browser making calls, response times drops to 50,000MS or worse.
  3. Each additional browser adds threads used by the API, e.g. 40 threads base, 2nd browser hitting endpoint leads to 52 threads, third spikes to 70, and so on.
  4. When one endpoint is loaded, the entire API returns slowly (all endpoints). This is my main reason for thinking "thread exhaustion", along with point #3.

当前代码如下:

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

我的理论是 return Authorized(authDto => 会保留一个线程,直到返回为止,这会导致线程耗尽.

My theory is that return Authorized(authDto => holds a thread until it returns, leading to thread exhaustion.

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

Authorized 是第三方库的一部分,所以我很难对此进行测试.想知道这是否是一个可能的问题/解决方案.

Authorized is part of a third-party library, so I can't test this easily. Would like to know if this looks like a likely problem/solution.

推荐答案

是的,异步等待可以减少线程耗尽.简而言之,当您生成的任务超出ThreadPool的处理能力时,就会出现线程耗尽.

Yes async await can reduce thread exhaustion. In a few words thread exhaustion arise when you generate more tasks than your ThreadPool can handle.

您可以在此处检查细微的特殊性:

There are subtle specifities that you can check here : Thread starvation and queuing

唯一需要牢记的是,您永远都不应阻塞任务内部.这意味着在异步等待状态下调用异步代码(并且永远不要在未完成的任务上使用.Wait或.Result).

The only thing that you have to keep in mind on your side is that you should never block inside a task. This implies calling asynchronous code with async await (and never using .Wait or .Result on a non finished task).

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

If you use some blocking code wich is not using the async await pattern you have to spawn it on a dedicated thread (not the task thread queue).

这篇关于使用异步等待是否可以避免线程耗尽?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆