我试图了解异步的工作原理,但有一种情况我已将其简化到最大程度,并且找不到任何解释。
在项目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
Task.Run(() => { Test.Work(id); }).Wait();
有时候是主线程之外的另一个线程,有时不是,我不理解。
Here如下:
Task.Run在线程池上启动一个任务以进行计算。的 ASP.NET线程池必须处理(意外地)丢失其线程之一 在此请求的持续时间内保持线程状态。
好的,在他的示例中没有Wait(),但是有什么区别,无论如何,在Work()之后调用Wait(),因此无论是否有Wait(),Work()都应始终具有相同的行为
如果有人可以给我一个解释,我将不胜感激。
答案 0 :(得分:1)
TPL可以在您等待时将任务内联到当前线程中。如果任务尚未在另一个线程上启动,则会发生这种情况。这是一项性能优化。
It is a very controversial feature that injects subtle bugs into applications.本质上,对任务的任何等待都可以不确定地运行任意代码。