为啥将 .Wait() 添加到我的 Task 有时会允许 Task 使用主线程?
Posted
技术标签:
【中文标题】为啥将 .Wait() 添加到我的 Task 有时会允许 Task 使用主线程?【英文标题】:Why does adding .Wait() to my Task sometimes allow the Task to use the main thread?为什么将 .Wait() 添加到我的 Task 有时会允许 Task 使用主线程? 【发布时间】:2019-02-14 22:36:08 【问题描述】:我试图了解异步是如何工作的,但有一种情况我已最大限度地简化了,但我找不到任何解释。
关于一个项目mvc asp.net framework 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(),但它有什么区别,Wait() 无论如何都会在 Work() 之后调用,所以无论是否存在 Wait(),Work() 都应该始终具有相同的行为.
如果有人能给我一个解释,我将不胜感激。
【问题讨论】:
任务在调度程序上运行。当您等待或等待时,可能会选择调用线程来执行其他工作。就像它正在等待的任务一样。 任务不是线程,但它们可能在另一个线程上运行。 但这不是现实世界的问题。当您在另一个线程上运行任务时,您不应该关心在哪个线程上。您有时会关心调用者将继续执行的线程。async
在 C# 中不是线程的同义词,而是创建一个可由任何线程完成的事件堆栈
这是在Task.Wait
中记录的:“如果当前任务尚未开始执行,Wait 方法会尝试从调度程序中删除任务并在当前线程”
【参考方案1】:
TPL 可以在您等待时将任务内联到当前线程中。如果任务尚未在另一个线程上启动,则可能会发生这种情况。这是一种性能优化。
It is a very controversial feature that injects subtle bugs into applications. 本质上,任何等待任务都可以不确定地运行任意代码。
【讨论】:
以上是关于为啥将 .Wait() 添加到我的 Task 有时会允许 Task 使用主线程?的主要内容,如果未能解决你的问题,请参考以下文章
为啥要将 entitlements.plist 添加到我的项目中?
为啥我需要调用 removeView() 才能将视图添加到我的 LinearLayout
为啥将 ViewModel 添加到我的 SwiftUI 应用程序后我的 UI 没有更新?
为啥每当我尝试将图像添加到我的 django 项目时都会出错?
尝试使用自动布局将 UIButton 添加到我的视图中,但它没有出现。为啥? [关闭]
我可以将 UITapGestureRecognizer 添加到我的控制器 self.view,但不能添加到任何自定义视图。为啥?