为什么要添加.等待()到我的任务有时允许任务使用主线程?



我试图了解异步的工作原理,但是有一种情况我已经简化到最大,我找不到任何解释。

在项目 mvc asp.net 框架 4.6 上:

...
public class Test {
public static void Work(int id) {
if (id == Thread.CurrentThread.ManagedThreadId) {
Debug.WriteLine("******************************");
Debug.WriteLine("***     BOOOMMMM !!!!!!!   ***");
Debug.WriteLine("******************************");
}
}
}
public class HomeController : Controller {
public ActionResult Index() {
var id = Thread.CurrentThread.ManagedThreadId;
Task.Run(() => { Test.Work(id); });
return View();
}
...

当我执行上面的代码时:

if (id == Thread.CurrentThread.ManagedThreadId)

从未验证。DoWork(( 运行在另一个线程上,而不是我的主线程。对我来说,这很正常,这是我在阅读过程中一直理解的。

但是如果我在任务上运行

等待
Task.Run(() => { Test.Work(id); }).Wait();

有时它是主线程以外的另一个线程,有时不是,我不明白。

这里写着:

Task.Run 在线程池上启动一个任务来执行计算。这 ASP.NET 线程池必须处理(意外地(丢失其之一 此请求持续时间内的线程。

好的,在他的示例中没有 Wait((,但它有什么区别,无论如何,Wait(( 是在 Work(( 之后调用的,所以无论是否有 Wait((,Work(( 都应该始终具有相同的行为。

如果有人能给我一个解释,我将不胜感激。

TPL 可以在您等待时将任务内联到当前线程中。如果任务尚未在另一个线程上启动,则可能会发生这种情况。这是一种性能优化。

这是一个非常有争议的功能,它将微妙的错误注入到应用程序中。从本质上讲,对任务的任何等待都可以不确定地运行任意代码。

最新更新