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?
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.
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.
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.
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.
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 await
s 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With