Poul K. Sørensen
Poul K. Sørensen

Reputation: 17540

is await task equal to throwing the exception of the faulted task in the ContinueWith

is the following not redundant?

await blob.CopyToBlobAsync(newBlob).
       ContinueWith((t) => { if (t.IsFaulted) throw t.Exception; });

as if there was not a ContinueWith call, the exception will be thrown directly?

When would one use continueWith instead of just await a task?

is the following the same ?

await myTask.ContinueWith(t => {'do something with the task t'});

and

await myTask;
'do something with the task MyTask'

Upvotes: 4

Views: 1206

Answers (1)

Stephen Cleary
Stephen Cleary

Reputation: 457057

The ContinueWith(t => { if (t.IsFaulted) throw t.Exception; }) line has different semantics than just awaiting the CopyToBlobAsync task directly:

  • It ignores cancellation results; the Task returned by ContinueWith will complete successfully even if the Task returned by CopyToBlobAsync is canceled. This may be intentional behavior.
  • It ignores successful results; any return value from CopyToBlobAsync is dropped.
  • It wraps any exceptions in an AggregateException by throwing t.Exception directly. This is almost certainly buggy behavior.

So it's not exactly redundant, and is probably a mistake.

You can use ContinueWith in some situations instead of awaiting a task. In my code, I usually only do this if the continuation is simple, I don't need the context in the continuation, and I don't want the overhead of the async state machine. For most situations, you should prefer await possibly combined with ConfigureAwait(false).

Your last examples are not the same; ContinueWith will execute on a thread pool by default, while await by default will capture a context and execute the continuation within that context. Also, you have to be very careful how you use the task in your continuation: you usually want exceptions and cancellation propagated to the continuation task, and that's not as easy as it first appears.

In short, I recommend await in almost every scenario. It's easier to write, easier to read, and has reasonable default behavior.

Upvotes: 4

Related Questions