This post originally appeared on Medium
Are you using ContinueWith in your async code?
For my future reference, this post is a quick summary of ASP.NET Core Architect David Fowler’s tweets:
David Fowler@davidfowlAre you using ContinueWith in your async code? If yes? Why? #dotnetcore #aspnetcore07:12 AM - 26 Sep 2018
So, here we go.
- Async state machines, though they have creation overhead are easier to debug. They can and will be further optimized in the future (on the runtime side).
- They execute synchronously if the task is already complete, something that
ContinueWith
doesn’t do this unless you specify the right set of flags. - Calling
ContinueWith
allocates another task per operation (it wraps your delegate in a task object) instead of re-using the state machine instance as the continuation. So you’re static callback is then wrapped in a ContinuationTask object. That then also gets wrapped in another continuation object and attached to the list of Task continuations…. Task itself is also is optimized for async/await over everything else.
For example:
if (!task.IsCompleted)
{
return FinishAsync(task);
}
private async Task FinishAsync(Task task)
{
try
{
await task;
}
catch (Exception ex)
{
Log(.....)
}
}
-
ContinueWith
allocates more than using async await. In fact, in .NET Core Task is very optimized for async await code paths and allocates less thanContinueWith
. - The state machine’s overhead is a concern when you finish synchronously, not asynchronously.
- If you take into account the whole “cost,” including the state machine generation, async/await is still lighter than just using
ContinueWith
in this situation. At least on .NET Core it is. -
ContinueWith
needs to capture the execution context. That’s going to mean at least an object that has both your callback and _ _options. - In the async await case, the state machine starts off as a
struct
and once you go async it is then boxed into an object, that boxing allocation is basically reused for everything.
Last but not least, also worth to check tweet thread:
Ben Adams@ben_a_adams@davidfowl @0omari0 @ThrowATwit @jbogard @DanielSilv9 @MoiTrades @marc_data So back to; with local function at top for @jbogard's .editorconfig23:41 PM - 26 Sep 2018
Check out this Async Guidance from David Fowler ✨
Summary
Use async/await.
Top comments (0)