我知道这是一个常见问题,但我已经阅读了大量文章并感到困惑。现在我认为最好不要阅读它们))。
那么,ASP.NET 是如何工作的(仅关于线程):
这种描述的行为正确吗?
当我在 ASP.NET MVC Controller 中启动新任务时,究竟会发生什么?
public ActionResult Index()
{
var task1 = Task.Factory.StartNew(() => DoSomeHeavyWork());
return View();
}
private static async Task DoSomeHeavyWork()
{
await Task.Delay(5000);
}
这是正确的吗 ?
现在让我们看看异步操作
public async Task<ActionResult> Index()
{
await DoSomeHeavyWork();
return View();
}
,我了解与以前的代码示例的区别,但不了解过程,在此示例中,行为如下:
请解释第 2 点和第 5 点之间发生的情况,问题是:
最佳答案
Is this described behaviour right ?
是的。
Is it correct ?
是的。
is the DoSomeHeavyWork processed inside task1 or where (where it is "awaited") ? I think this a key question.
从当前代码,
DoSomeHeavyWork
将异步等待 Task.Delay
去完成。是的,这将发生在线程池分配的同一个线程上,它不会旋转任何新线程。但是,不能保证它会是同一个线程。which thread will continue to process the request after await?
因为我们讨论的是 ASP.NET,这将是一个任意线程池线程,
HttpContext
编码到它上面。如果这是 WinForms 或 WPF 应用程序,您将在 await
之后再次访问 UI 线程。 ,假设您不使用 ConfigureAwait(false)
.request produces thread allocating from the thread pool, but response will not be sent until the DoSomeHeavyWorkAsync finished and it doesn't matter in which thread this method executes. In other words, according to single request and single concrete task (DoSomeHeavyWork) there is no benefits of using async. Is it correct ?
在这种特殊情况下,您不会看到异步的好处。当您有并发请求访问服务器时,异步会发光,并且其中很多都在执行 IO 绑定(bind)工作。例如,在访问数据库时使用异步时,您可以在查询执行的时间内释放线程池线程,从而允许同一线程同时处理更多请求。
But how IO completion thread calls back thread pool thread in this case ?
您必须将并行性和并发性分开。如果您需要计算能力来并行执行 CPU 密集型工作,那么异步不是实现它的工具。另一方面,如果您有大量并发的 IO 绑定(bind)操作,例如为 CRUD 操作访问数据库,您可以通过在执行 IO 操作时释放线程来从使用异步中受益。这是异步的主要关键点。
线程池具有专用的 IO 完成线程池以及工作线程,您可以通过调用
ThreadPool.GetAvailableThreads
查看。 .当您使用 IO 绑定(bind)操作时,检索回调的线程通常是 IO 完成线程,而不是工作线程。他们都有不同的游泳池。
关于ASP.NET 和异步 - 它是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30391687/