等待空任务永远旋转(等待新任务(() => { }))

本文关键字:等待 新任务 永远 旋转 任务 | 更新日期: 2023-09-27 18:33:04

我正在尝试了解此代码:

 [TestFixture]
 public class ExampleTest
 {
    [Test]
    public void Example()
    {
        AwaitEmptyTask().Wait();
    }
    public async Task AwaitEmptyTask()
    {
        await new Task(() => { });
    }
 }

该方法永远不会Example结束并永远停止。 为什么??

修复(来自异步单元测试中的存根任务返回方法(是将await new Task( () => {})替换为return Task.FromResult<object>(null);但同样,为什么有必要这样做?

我知道有很多类似的问题,但我见过的问题似乎都没有解释为什么会发生这种情况:

  • 返回任务的等待方法 - 永远旋转?:我正确包含了await关键字 AFAIK
  • 根 异步单元测试中的任务返回方法:不解释原因。
  • 如果从静态构造函数启动并等待,为什么空的.NET任务将无法完成? 我没有在静态上下文中运行,据我所知上下文是一致的
  • 异步方法返回 null:也给出了解决方案,但没有解释原因
  • 异步等待返回 任务:讨论Task.FromResult但不讨论await new Task(() => {})不起作用的原因

等待空任务永远旋转(等待新任务(() => { }))

您正在创建一个任务,但从未启动它,因此它永远不会完成。

您应该使用 Task.Run 来创建要立即开始执行的任务,而不是使用 Task 构造函数。

您需要

在任务上调用Start()

否则,它将永远不会完成。

即使您将其更改为

await Task.Run(() => { });

它可能仍然永远不会完成。当您点击此行时,程序将创建一个延续任务,该任务将在任务完成时继续。任务为空这一事实无关紧要。此时,控制流返回到

AwaitEmptyTask().Wait();

等待任务完成并阻止当前线程

任务完成后,它会尝试在当前线程上继续。但是,它不能,因为线程被对 Wait(( 的调用阻塞。

将等待的行更改为

await Task.Run(() => { }).ConfigureAwait(false);

这是一个常见的死锁问题。不要混合 Wait(( 和 await。见 http://msdn.microsoft.com/en-us/magazine/jj991977.aspx