I was wondering what is the best/correct way of writing asynchronous code that is composed of two (or more) async and dependent (the first have to finish to execute second) operations.
Example with async/await:
await RunFirstOperationAsync();
await RunSecondOperationAsync();
Example with Continuation:
await RunFirstOperationAsync()
.ContinueWith(t => RunSecondOperationAsync());
You'd want to use await
if you possibly can.
ContinueWith
has a number of issues. I describe this briefly in my blog post on why ContinueWith
is dangerous, which builds on my earlier blog post on why StartNew
is dangerous (they share many of the same issues).
In particular:
ContinueWith
does not have a good default TaskScheduler
. The default task scheduler is TaskScheduler.Current
(not TaskScheduler.Default
), and resuming on the current SynchronizationContext
must be done by hand if desired.
ContinueWith
has non-ideal default options. For asynchronous code, you would want DenyChildAttach
and ExecuteSynchronously
, at least.
ContinueWith
does not understand asynchronous continuations, which generally requires an additional Unwrap
call to work around this limitation.
ContinueWith
treats its CancellationToken
argument in a surprising way. More on that in this blog post of mine.
These arguments are all summarized on my blog post on Task continuations. await
does not have any of these drawbacks.