Task.Run 在 ASP .NET MVC Web 应用程序中被认为是不好的做法吗? [英] Is Task.Run considered bad practice in an ASP .NET MVC Web Application?

查看:25
本文介绍了Task.Run 在 ASP .NET MVC Web 应用程序中被认为是不好的做法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们目前正在开发一个 Web 应用程序,它依赖于 ASP .NET MVC 5、Angular.JS 1.4、Web API 2 和 Entity Framework 6.出于可扩展性的原因,Web 应用程序的繁重性依赖于 async/await 模式.我们的域需要一些 CPU 密集型计算,这可能需要几秒钟(<10 秒).过去,一些团队成员使用 Task.Run,​​以加快计算速度.由于在 ASP .NET MVC 或 Web API 控制器中启动额外线程被认为是一种不好的做法(该线程不被 IIS 识别,因此不在 AppDomain Recycle 上考虑 => 参见 Stephen Cleary 的博客文章),他们使用 ConfigureAwait(false).

We are currently developing a web application, which relies on ASP .NET MVC 5, Angular.JS 1.4, Web API 2 and Entity Framework 6. For scalability reasons, the web application heavility relies on the async/await pattern. Our domain requires some cpu-intensive calculations, which can takes some seconds (<10s). In the past some team members used Task.Run, in order to speed up the calculations.Since starting an extra thread inside ASP .NET MVC or Web API controllers is considered a bad practise (the thread is not known by the IIS, so not considered on AppDomain Recycle => See Stephen Cleary's blog post), they used ConfigureAwait(false).

public async Task CalculateAsync(double param1, double param2)
{
    // CalculateSync is synchronous and cpu-intensive (<10s)
    await Task.Run(() => this.CalculateSync(param1, param2))).ConfigureAwait(false);
}

问题

  • 在异步 Web API 控制器中使用 Task.Run 进行 CPU 绑定操作是否有任何性能优势?
  • ConfigureAwait(false) 真的能避免创建额外的线程吗?
  • 推荐答案

    在异步 Web API 控制器中使用 Task.Run 进行 cpu 绑定操作是否有任何性能优势?

    Is there any performance benefit in using Task.Run in an async Web API Controller for cpu-bound operations?

    零.没有任何.事实上,您通过生成一个新线程来阻碍性能.在 Web 应用程序的上下文中,生成线程与在后台"运行不同.这是由于 Web 请求的性质造成的.当有传入请求时,会从池中取出一个线程来为请求提供服务.使用 async 允许在请求结束之前返回线程,if 并且仅当线程处于等待状态,即空闲时.生成一个线程来处理,有效地使主线程空闲,允许它返回到池中,但您仍然有一个活动线程.将原始线程返回到池中此时什么都不做.然后,当新线程完成其工作时,您必须从池中请求返回一个主线程,并最终返回响应.在所有工作完成之前无法返回响应,因此无论您使用 1 个线程还是 100 个线程,异步或同步,直到一切都完成后才能返回响应.因此,使用额外的线程只会增加开销.

    Zero. None. In fact, you're hindering performance by spawning a new thread. Within the context of a web application, spawning a thread is not the same thing as running in the "background". This is due to the nature of a web request. When there's an incoming request, a thread is taken from the pool to service the request. Using async allows the thread to be returned before the end of the request, if and only if the thread is in a wait-state, i.e. idle. Spawning a thread to do work on, effectively idles the primary thread, allowing it to be returned to the pool, but you've still got an active thread. Returning the original thread to the pool does nothing at that point. Then, when the new thread finishes its work, you've got to request a main thread back from the pool, and finally return the response. The response cannot be returned until all work has completed, so whether you use 1 thread or a hundred, async or sync, the response cannot be returned until everything finishes. Therefore, using additional threads does nothing but add overhead.

    ConfigureAwait(false) 真的避免了额外线程的创建吗?

    Does ConfigureAwait(false) really avoid the creation of an extra thread?

    不,或者更恰当地说,不是这个.ConfigureAwait 只是一个优化提示,只判断线程跳转之间是否保持原始上下文.总之,它与线程的创建无关,至少在 ASP.NET 应用程序的上下文中,无论哪种方式对性能的影响都可以忽略不计.

    No, or more appropriately, it's not about that. ConfigureAwait is just an optimization hint, and only determines whether the original context is maintained between thread jumps. Long and short, it has nothing to do with the creation of a thread, and at least in the context of an ASP.NET application, has negligible performance impact either way.

    这篇关于Task.Run 在 ASP .NET MVC Web 应用程序中被认为是不好的做法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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