任务等待混乱

时间:2016-04-06 18:30:53

标签: c# asynchronous async-await task

我有以下

async void A () {
  await B();
}

async Task B () {
  await Task.Factory.StratNew( ()=> C());
}

async Task C () {
  while (true) {
    //await Task.Factory.StartNew(()=> {Thread.Sleep(5000);});
    Thread.Sleep(5000);
  }
}

在上面的程序中,A永远不会返回,因为C内的while循环。但是,如果我取消注释C和KEEP Thread.Sleep(5000)中的行,A会立即返回。有人可以解释那里发生了什么吗?

2 个答案:

答案 0 :(得分:3)

主要问题在文章Task.Run vs Task.Factory.StartNew中有详细描述。如果您要更改这样的代码,您会看到我的想法。

async void A()
{
    await B(); 
}

async Task B()
{
    // await Task.Factory.StartNew(() => C());
    await Task.Run(async () => await C());
    // await Task.Run(() => C()); // this would still produce the same effect
}

async Task C()
{
    while (true)
    {
        await Task.Delay(5000);
        //Thread.Sleep(5000);
    }
}

另见previous answer by Stephen Cleary。基本上Task.Factory.StartNew不尊重async/await模型,您确实应该使用Task.Run代码async/awaitTask.Factory.StartNew创建并启动一个新任务,而不是在等待结果,除非同步执行返回的任务,这是在C内删除await时发生的。

答案 1 :(得分:2)

当你在无限循环中“等待”时,运行时会中断无限循环,导致执行外部调用,从而有机会完成B(并因此返回A)然后返回无限循环。

如果没有“等待”,B(并因此A)就无法完成,他们将永远“等待”。