Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens if I don't await a task?

Tags:

c#

async-await

Consider this example:

var task = DoSomething() bool ready = await DoSomethingElse(); if (!ready)    return null;  var value = await DoThirdThing(); // depends on DoSomethingElse return value + await task; 

DoSomething does some very important work that may take a while, thus we start it off first.
In the meantime we check whether we're ready with DoSomethingElse and exit early if not.
We call DoThirdThing only if we are ready, as the universe might otherwise explode.

We cannot use Task.WhenAll as DoThirdThing depends on DoSomethingElse and we also don't want to wait for DoSomething because we want to call the other two methods concurrently if possible.

The question: What happens to task if we're not ready and exit early?

Will any exceptions that it throws be re-thrown by a SynchronizationContext?
Are there problems if task completes normally, as nobody consumes its value?

Follow-up: Is there a neat way to make sure task is awaited?

We could simply await task if we are not ready, however if there were 50 exit conditions this would be very tedious.
Could a finally block be used to await task and re-throw potential exceptions? If task completed normally it would be awaited again in the finally block, but that shouldn't cause any problems?

like image 219
enzi Avatar asked Oct 12 '15 16:10

enzi


People also ask

What happens when 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.

Do I have to await Task run?

If it is some trivial operation that executes quickly, then you can just call it synchronously, without the need for await . But if it is a long-running operation, you may need to find a way to make it asynchronous.

Can we use task without async await?

C# Language Async-Await Returning a Task without awaitMethods that perform asynchronous operations don't need to use await if: There is only one asynchronous call inside the method. The asynchronous call is at the end of the method. Catching/handling exception that may happen within the Task is not necessary.

What exactly does await do?

An await is an asynchronous wait. It is not a blocking call and allows the caller of your method to continue. The remainder of the code inside the method after an await will be executed when the Task returned has completed. In the first version of your code, you allow callers to continue.


1 Answers

The question: What happens to task if we're not ready and exit early?

Nothing. The code ignores the task, so the task is ignored.

Will any exceptions that it throws be re-thrown by a SynchronizationContext?

No. They will (eventually) be passed to TaskScheduler.UnobservedTaskException and then ignored.

Are there problems if task completes normally, as nobody consumes its value?

Nope.

Follow-up: Is there a neat way to make sure task is awaited?

No.

Could a finally block be used to await task and re-throw potential exceptions?

Yes, if your code actually awaits the task. Presumably this would mean saving the task somewhere.

If task completed normally it would be awaited again in the finally block, but that shouldn't cause any problems?

You can await a task as many times as you like.

We could simply await task if we are not ready, however if there were 50 exit conditions this would be very tedious.

Then consider restructuring your code.

like image 89
Stephen Cleary Avatar answered Sep 22 '22 11:09

Stephen Cleary