我知道这是一个常见的问题,但我读过一篇文章并感到困惑。现在我认为最好不要阅读它们。)。
那么,ASP.NET如何工作(仅关于线程):
这描述的行为是对的吗?
当我在ASP.NET MVC控制器中启动新任务时会发生什么?
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点之间发生的事情,问题是:
答案 0 :(得分:6)
这描述的行为是对的吗?
是
这是对的吗?
是
是在task1或其中(在何处)处理的DoSomeHeavyWork &#34;等待&#34;)?我认为这是一个关键问题。
从当前代码中,DoSomeHeavyWork
将异步等待Task.Delay
完成。是的,这将发生在线程池分配的同一个线程上,它不会旋转任何新线程。但是,并不能保证它将是相同的线程。
在等待之后哪个线程将继续处理请求?
因为我们正在讨论ASP.NET,所以它将是一个任意的线程池线程,HttpContext
封送在它上面。如果这是WinForms或WPF应用,那么您将在await
之后再次访问UI线程,因为您不会使用ConfigureAwait(false)
。
请求生成从线程池分配的线程,但响应 在DoSomeHeavyWorkAsync完成之前不会发送它 这个方法在哪个线程中执行并不重要。换一种说法, 根据单一要求和单一具体任务(DoSomeHeavyWork) 使用异步没有任何好处。这是对的吗?
在这种特殊情况下,您不会看到异步的好处。当你有并发请求命中服务器时,异步会闪耀,而且很多都在进行IO绑定工作。例如,当您在访问数据库时使用异步时,您可以在查询执行的时间内释放线程池线程,从而允许同一个线程同时处理更多请求。
但IO完成线程如何在此回调线程池线程 案件?
您必须将并行性和并发性分开。如果你需要计算能力来并行执行CPU绑定工作,async就不是实现它的工具。另一方面,如果你有很多并发 IO绑定操作,比如命中数据库进行CRUD操作,你可以通过释放线程来使用async,而IO操作则是执行。这是异步的主要关键点。
线程池具有专用的IO完成线程池以及工作线程,您可以通过调用ThreadPool.GetAvailableThreads
来查看它们。当您使用IO绑定操作时,检索回调的线程通常是 IO完成线程,而不是工作线程。他们都有不同的游泳池。