【发布时间】:2015-05-22 17:16:42
【问题描述】:
我知道这是一个常见问题,但我阅读了大量文章并感到困惑。现在我认为最好不要阅读它们))。
那么,ASP.NET 是如何工作的(仅关于线程):
- http 请求由线程池中的线程提供服务。
- 当请求正在处理时,这个线程很忙,因为请求正在这个线程内处理。
- 请求处理完成后,线程返回线程池,服务器发送响应。
这种描述的行为正确吗?
当我在 ASP.NET MVC 控制器中启动新任务时,会发生什么?
public ActionResult Index()
{
var task1 = Task.Factory.StartNew(() => DoSomeHeavyWork());
return View();
}
private static async Task DoSomeHeavyWork()
{
await Task.Delay(5000);
}
- 控制器操作开始在处理当前请求的线程内执行 - T1。
- 线程池为task1分配了另一个线程(T2)。
- task1 在 T2 内“立即”启动。
- 查看结果“立即”返回。
- ASP.NET 做一些工作,服务器发送响应,T1 返回线程池,T2 还活着。
- DoSomeHeavyWork 完成一段时间后,T2 线程将返回线程池。
对吗?
现在让我们看看异步操作
public async Task<ActionResult> Index()
{
await DoSomeHeavyWork();
return View();
}
,我了解与之前代码示例的区别,但不了解过程,在此示例中行为如下:
- 动作开始在处理当前请求的线程内执行 - T1。
- DoSomeHeavyWork “立即”返回一个任务,我们也称它为“task1”。
- T1 返回线程池。
- DoSomeHeavyWork 完成后,Index 操作继续执行。
- 执行索引操作后,服务器将发送响应。
请解释第 2 点和第 5 点之间发生了什么,问题是:
- DoSomeHeavyWork 是在 task1 内处理还是在哪里(“等待”的地方)处理?我认为这是一个关键问题。
- 等待后哪个线程将继续处理请求 - 线程池中的任何新线程,对吧?
- request 产生从线程池分配的线程,但是在 DoSomeHeavyWorkAsync 完成之前不会发送响应,并且该方法在哪个线程中执行都没有关系。换句话说,根据 single 请求和 single 具体任务(DoSomeHeavyWork),使用异步没有任何好处。对吗?
- 如果前面的陈述是正确的,那么我不明白异步如何提高具有相同单个任务的多个请求的性能。我会尽力解释。假设线程池有 50 个线程可用于处理请求。单个请求至少应该由线程池中的一个线程处理,如果该请求启动了另一个线程,那么它们都将从线程池中取出,例如request 需要一个线程来处理自己,并行启动 5 个不同的任务并等待所有任务,线程池将有 50 - 1 - 5 = 44 个空闲线程来处理传入的请求 - 所以这是一种并行性,我们可以提高单个任务的性能请求,但我们减少了可以处理的请求数量。因此,根据 ASP.NET 中的请求处理,我认为只有以某种方式启动 IO 完成线程的任务才能实现异步(TAP)的目标。但是这种情况下 IO 完成线程如何回调线程池线程呢?
【问题讨论】:
-
await这个问题的一些有价值的答案。
标签: asp.net asp.net-mvc async-await task-parallel-library