asp.net - 我应该将工作卸载到 ASP.NET 中的其他线程吗?

标签 asp.net .net multithreading asynchronous async-await

我正在创建 ASP.NET Web API,其中某些操作(同步、遗留代码)可能需要一些时间(主要是 IO 限制,但也有一些计算密集型的东西)。

我知道每个传入请求都从线程池中分配了一个线程,但我对其余部分有点模糊。请求线程是否以某种方式“特殊”,保证将工作卸载到其他线程以避免锁定它?卸载对线程池饥饿和拒绝请求有帮助吗?如果是这样,我是否需要一直为每个可能长时间运行的函数创建一个异步包装器,还是只需要一个最高级别的异步包装器?

最佳答案

为长时间运行的任务创建异步包装器在 ASP.NET 上下文中毫无意义,只会在几个方面损害性能。

在卸载 GUI 线程或其他特殊线程时,在线程池线程上异步运行同步方法是有意义的。在这种情况下,该方法应由该特殊线程上的调用者以调用者认为合适的任何方式异步调用(使用例如 Task.Run ,通常不应在异步方法的实现中使用)。然而,在 ASP.NET 中,只有线程池线程,出于多种原因,不需要(实际上不应该)以这种方式卸载。

Stephen Cleary(毕竟他写了一本关于 C# 并发的书)在博客文章 Task.Run Etiquette Examples: Don't Use Task.Run in the Implementation 中最清楚地说明了这一点。

That’s why one of the principles of ASP.NET is to avoid using thread pool threads (except for the request thread that ASP.NET gives you, of course). More to the point, this means that ASP.NET applications should avoid Task.Run.

[...]

In fact, the only place we really need an asynchronous calculation is when we call it from the UI thread.



强烈推荐整篇文章,重点介绍在 ASP.NET 中卸载的各种问题。

进一步阅读:
  • This SO answer
  • 斯蒂芬·图布:Should I expose asynchronous wrappers for synchronous methods?
  • 本·莫里斯:Why you shouldn’t create asynchronous wrappers with Task.Run()
  • 关于asp.net - 我应该将工作卸载到 ASP.NET 中的其他线程吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49275861/

    相关文章:

    c# - 为什么不能在 Page.PreInit 事件之后动态应用主题和母版页?

    一起显示多个月份的 ASP.NET 日历

    python - 带有 python 循环的多线程

    asp.net - 识别唯一的浏览器/选项卡实例,例如用户在 mysite.com 上打开了 2 个选项卡 - 分别识别

    .net - 如何获取 ManagementObjects 的计数(WMI 结果)而不通过 .NET 中的集合进行枚举

    .net - 严重依赖存储过程的应用程序

    c# - 使用性能计数器计算平均值

    java - 运行外部可执行文件 (.exe) 并等待其完成

    Java 创建 BufferedImage 实例卡住程序

    c# - Startup.cs 方法 app.MapSignalR() 不在 signalR-2.0 中生成集线器