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

时间:2014-12-04 15:54:41

标签: c# .net asynchronous async-await task

我试图了解这段代码:

 [TestFixture]
 public class ExampleTest
 {
    [Test]
    public void Example()
    {
        AwaitEmptyTask().Wait();
    }

    public async Task AwaitEmptyTask()
    {
        await new Task(() => { });
    }
 }

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

修复(来自Stubbing Task returning method in async unit test)是将await new Task( () => {})替换为return Task.FromResult<object>(null);但是,为什么还需要这样做?

我知道有很多问题与此类似,但我所看到的似乎没有解释为什么会这样:

3 个答案:

答案 0 :(得分:18)

你正在创建一个任务并且永远不会启动它,所以它永远不会完成。

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

答案 1 :(得分:8)

您需要在任务上致电Start()

否则,它永远不会完成。

答案 2 :(得分:6)

即使您将其更改为

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

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

AwaitEmptyTask().Wait();

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

当任务完成时,它会尝试继续当前线程。但是,它不能,因为线程被Wait()调用阻止。

将等待的行更改为

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

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