【问题标题】:Difference between Task.Run(()=> DoWorkAsync()) and new Thread(async()=> DoWorkAsync());Task.Run(()=> DoWorkAsync()) 和 new Thread(async()=> DoWorkAsync()); 的区别
【发布时间】:2021-12-29 06:16:14
【问题描述】:

我最近遇到了一些让我很困惑的代码,我一直认为你必须使用线程或异步任务,而不是在它们之间混搭,

public async Task DoWork()
{
   Task.Delay(1000);
}

现在我看到代码是这样调用的:

public void Main()
{
    var thread = new Thread(async () => { await DoWorkAync(); })
                {
                    Priority = ThreadPriority.Highest,
                    IsBackground = true
                };
        // Start thread
        proccessThread.Start();
}

现在这神奇地似乎没有在每次运行时创建一个线程,它似乎正在使用ThreadPool

现在我很难理解的是上述和以下之间的区别:

public void Main()
{
 var task = Task.Run(DoWorkASync);
}

从我的测试来看,似乎 C# 线程在传入异步表达式与运行的标准方法时具有不同的功能>

【问题讨论】:

  • 这很令人困惑,因为每个 sn-p 本身都是错误的。首先,没有等待。在第二个中,启动了与创建的线程不同的线程,在第三个中再次启动:不等待任务完成。
  • Thread 构造函数不知道async,因此线程将启动异步任务并立即完成,而无需等待异步处理完成。

标签: c# multithreading async-await task threadpool


【解决方案1】:

这个结构:

var thread = new Thread(async () => { await DoWorkAync(); });
    // Start thread
proccessThread.Start();

调用Thread构造函数重载接受ThreadStart委托,而ThreadStart委托是() => void。所以你有这个:

var thread = new Thread(StuffYourThreadExecutes);
thread.Start();   

static async void StuffYourThreadExecutes() {
    await DoWorkAsync();
}

因此,您启动新线程并运行代码,直到第一个异步操作开始。然后线程存在。在第一个异步操作完成之后 - 其余的在任何线程任务调度程序提供程序(通常是线程池线程)上执行。在此过程中发生的任何异常都无法观察到。

例如,如果DoWorkAsync 类似于:

static async Task DoWorkAsync(){
    await Task.Delay(1000);
}

然后线程启动并几乎立即退出,没有做任何有用的事情。

Task.Run,在那里传递异步委托时,执行文档中所述的操作:

将指定的工作排入队列以在线程池上运行并返回一个 任务的代理

所以整个操作只是在线程池线程上运行,而不是白白创建线程。您可以通过等待Task.Run 返回的任务来观察异常。

【讨论】:

  • 谢谢这是有道理的,所以如果我理解正确,正确的方法是使用Task.Run() 方式而不是新线程方式。
  • 是的,新线程方式这样使用首先是没用的,其次是危险的,因为你甚至无法观察到异常。
  • @Zapnologica 正确的做法是直接调用DoWorkAsync;没有new Thread,也没有Task.Run。除非你有一个 UI 线程,并且 DoWorkAsync 做了足够多的同步工作来影响 UI 响应能力。在这种情况下,使用Task.Run 将工作卸载到线程池。
  • “在这个过程中发生的任何异常都无法观察到。”:这句话有点含糊。人们可能会将 notobserved 解释为 fire-and-forget,但事实并非如此。在async void 方法启动时捕获的同步上下文中重新抛出async void 方法中引发的异常,这会导致进程崩溃(在大多数情况下)。
猜你喜欢
  • 2017-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多