Awaiting an empty Task spins forever (await new Task(() => { }))

I'm trying to get my head around this code:

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

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

The method Example never ends and blocks forever. Why??

The fix (from Stubbing Task returning method in async unit test) is to replace await new Task( () => {}) with return Task.FromResult<object>(null); but again, why is this necessary?

I know there are a bunch of questions similar to this one, but none that I've seen seem to explain why this is happening:

  • Await method that returns Task - spins forever?: I included the await keyword AFAIK correctly
  • Stubbing Task returning method in async unit test: Doesn't explain why.
  • Why will an empty .NET Task not complete if started and waited for from a static constructor?: I'm not running in a static context and as far as I can tell the context is consistent
  • Async methods return null: also gives the solution, but doesn't explain why
  • async await return Task: discusses Task.FromResult but not why await new Task(() => {}) doesn't work

  • You're creating a task and never starting it, so it never finishes.

    You should be using Task.Run to create a task that you want to start executing immediately, rather than using the Task constructor.


    You need to call Start() on your task.

    Otherwise, it will never finish.


    Even if you changed it to

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

    it may still never complete. When you hit this line, the program creates a continuation task that will continue when the task completes. The fact that the task is empty is irrelevant. At that point, control flow goes back to

    AwaitEmptyTask().Wait();
    

    which waits for the task to complete and blocks the current thread.

    When the task does complete, it attempts to continue on the current thread. However, it can't, because the thread is blocked by the call to Wait().

    Change the awaited line to

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

    This is a common deadlocking problem. Don't mix Wait() and await. See http://msdn.microsoft.com/en-us/magazine/jj991977.aspx

    链接地址: http://www.djcxy.com/p/79318.html

    上一篇: 这是异步的正确图表

    下一篇: 等待一个空的Task永久旋转(等待新任务(()=> {}))