使用异步方法等待 Task.Run 不会在正确的线程上引发异常

Posted

技术标签:

【中文标题】使用异步方法等待 Task.Run 不会在正确的线程上引发异常【英文标题】:Awaiting Task.Run with async method does not throw exception on correct thread 【发布时间】:2016-03-14 01:53:58 【问题描述】:

在运行下面的测试方法时,我发现即使我等待一个抛出异常的任务,测试也通过了。此外,会弹出一个单独的窗口,显示“QTAgent.exe 已停止工作”。这表明异常不会传播到运行测试的线程,而是杀死一个单独的线程。

我想知道为什么会这样。另外,由于这似乎没有按预期工作,我应该如何在线程池线程上运行异步方法?

请注意,如果我将其更改为 func 不是异步的,则会按预期在测试线程中引发异常。

 [TestMethod]
 public async Task TestWeirdTaskBehavior()
 
      Action func = async () =>
      
           await Task.Delay(0);
           throw new InvalidOperationException();
      ;
      await Task.Run(func);
 

【问题讨论】:

【参考方案1】:

简单的调整:

[TestMethod]
public async Task TestWeirdTaskBehavior()

    Func<Task> func = async () =>
    
        await Task.Delay(0);
        throw new InvalidOperationException();
    ;
    await Task.Run(func);

您的Action 本质上是async void。如果您想等待它或将其包装在另一个 Task 中,您需要编译器为您吐出一个 Task。在您原来的 sn-p 中,一旦内部任务遇到第一个 await,外部任务 (Task.Run(...)) 就会完成,之前抛出异常。

【讨论】:

哇!就在这上面浪费了半天时间。我在 SO 和其他网站上尝试了几个线程,但没有任何乐趣。直到最后我遇到了这个小问题。这是我希望编译器发现的一种东西。非常感谢!!

以上是关于使用异步方法等待 Task.Run 不会在正确的线程上引发异常的主要内容,如果未能解决你的问题,请参考以下文章

Task.Run() 代码是不是异步执行?

Task.Run()方法总结

async await task.run xamarin 表单

如何启动并等待 Task 运行

在 Task.Run() 中包装同步调用以使其异步有益吗?

如何对带有异步的流进行单元测试