The ContinueWith(t => { if (t.IsFaulted) throw t.Exception; }) line ContinueWith(t => { if (t.IsFaulted) throw t.Exception; }) has different semantics than just await directly in the CopyToBlobAsync task:
- It ignores the cancellation results;
Task returned by ContinueWith will succeed even if the Task returned by CopyToBlobAsync is canceled. This may be intentional behavior. - He ignores successful results; any return value from
CopyToBlobAsync discarded. - It overrides any exceptions in an
AggregateException by throwing a t.Exception directly. This is an almost useless behavior.
Thus, this is not unnecessary and probably a mistake.
You can use ContinueWith in some situations instead of await the task. In my code, I usually do this only if the continuation is simple, I do not need the context in the continuation, and I do not want the overhead of the async state machine. For most situations, you should prefer await , perhaps in combination with ConfigureAwait(false) .
Your latest examples do not match; ContinueWith will execute on the default thread pool, and await will grab the context by default and continue in that context. In addition, you must be very careful how you use the task in your continuation: you usually want exceptions and cancellations to be extended to the continuation task, and this is not as simple as it seems at first glance.
In short, I recommend await almost every scenario. It is easier to write, easier to read, and has reasonable default behavior.
source share