Async/Await best practices

Here are some best practices on async/await programing model based on reading from:

  1. Use ‘async Task’ or ‘async Task<T>’ instead of ‘async void’. Why? Primarily because of error-handling semantics. When using ‘async void’, any exception thrown will be raised directly on the SynchronizationContext that was active when the async void method started. When using ‘async Task’, exception is captured and plated on the Task object. The exception is asynchronous event handlers, which must regturn void (ex: ICommand.Execute implementations)
  2. Async code works best if it goes all the way from bottom up (or top down). That means that you shouldn’t mix synchronous and asynchronous code without considering the consequences or blocking async code with .Wait or .Result. This can result in deadlocks depending on the type of the SynchronizationContext (GUI or ASP.NET). The second issue with Wait/Result is the complex error handling as exceptions are wrapped in AggregateException and thrown.
  3. Proper context configuration enables better parallelism as some asynchronous code can run in parallel with the GUI thread instead of concurrently on the same thread due to the SynchronizationContext. This also avoids deadlocks. However, you should not use ConfigureAwait(false) if code after the await needs the original context.


Some tips:

Problem Solution
Create a task to execute code Task.Run or TaskFactory.StartNew
Create a task wrapper for an operation or event TaskFactory.FromAsync or TaskCompletionSource<T>
Support cancellation CancellationTokenSource and CancellationToken
Report progress IProgress<T> and Progress<T>
Handle streams of data TPL Dataflow or Reactive Extensions
Synchronize access to a shared resource SemaphoreSlim
Asynchronously initialize a resource AsyncLazy<T>
Async-ready producer/consumer structures TPL Dataflow or AsyncCollection<T>

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.