Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
like image 529
Philip Pittle Avatar asked Dec 04 '14 15:12

Philip Pittle


People also ask

What is awaited task in C#?

The await operator suspends evaluation of the enclosing async method until the asynchronous operation represented by its operand completes. When the asynchronous operation completes, the await operator returns the result of the operation, if any.

How do I return a task in C#?

The Task<TResult> return type is used for an async method that contains a return statement in which the operand is TResult . In the following example, the GetLeisureHoursAsync method contains a return statement that returns an integer. The method declaration must specify a return type of Task<int> .

What happens if you don't await a task?

If you don't await the task or explicitly check for exceptions, the exception is lost. If you await the task, its exception is rethrown. As a best practice, you should always await the call. By default, this message is a warning.

Does await create a new task C#?

No, async await is just made to allow code to run whilst something else is blocking, and it doesn't do Task.


1 Answers

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.

like image 135
Servy Avatar answered Oct 06 '22 00:10

Servy