为啥将 .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,但不能添加到任何自定义视图。为啥?