Thursday, November 19, 2015

C# Async Await Cheatsheet



     Asynchronous programming is difficult. Fortunately, C# has all the wonders of the Task Parallel Library to help us out. However, there is still a need to understand what properties we get with an async function definition, or what kind of properties we get when awaiting a task versus calling .Wait(). Knowing the properties will leave us better prepared to make decisions around which method we wish to use. So I made a little async await cheat sheet to help remember the properties of the different task scenarios. Enjoy~

A pdf version to take along with you can be found here.


o    Task Usage:

•         Task<int> longTask = LongRunningCalculation()
—  Task starts immediately.
—  Runs to first await in LongRunningCalculation() on current thread.
—  Returned Task<int> can be passed around to be awaited in the future.

•         await longTask
—  Does not block current thread.
—  Unwraps Task<int> into int.
—  Throws first exception that is triggered.

•         longTask.Wait()
—  Blocks current thread until longTask has completed.
—  Throws AggregateException which needs to be unwrapped to find triggered exception.

•         longTask.Wait(Timespan.FromSeconds(5))
—  Blocks current thread until longTask has completed or the timeout has occurred.
—  Throws AggregateException which needs to be unwrapped to find triggered exception.
—  Returns true when longTask ran to completion, and false when longTask timed out.
—  longTask may still be running even after the timeout.

•         longTask.Result
—  Blocks current thread until longTask has completed.
—  Unwraps Task<int> into int.
—  Throws AggregateException which needs to be unwrapped to find triggered exception.

•         longTask.GetAwaiter().GetResult()
—  Blocks current thread until longTask has completed.
—  Unwraps Task<int> into int.
—  Throws first exception that is triggered.

o    Batch Task Usage:

•         Task<int>[] longTasks =
{ LongRunningCalculation(), LongRunningCalculation(), LongRunningCalculation() }
—  All tasks start immediately.
—  All tasks run to first await in each LongRunningCalculation() on current thread.

•         Task.WhenAll(longTasks)
—  Batches up all of longTasks into a single awaitable task.
—  Runs all of longTasks in parallel when scheduling permits.
—  Returned Task<int[]> can be passed around to be awaited in the future.

•         await Task.WhenAll(longTasks)
—  Does not block current thread.
—  Unwraps Task<int[]> into int[].
—  Finishes running all tasks before any exception is thrown.
—  Throws first exception that is triggered.

•         Task.WaitAll(longTasks)
—  Blocks current thread until all longTasks have completed.
—  Finishes running all tasks before any exception is thrown.
—  Throws AggregateException which needs to be unwrapped to find triggered exception.

•         Task.WaitAll(longTasks, Timespan.FromSeconds(5))
—  Blocks current thread until all longTasks have completed or the timeout has occurred.
—  Finishes running all tasks before exception is thrown.
—  Throws AggregateException which needs to be unwrapped to find triggered exception.
—  Returns true when longTasks all ran to completion, and false when longTasks timed out.
—  longTasks may still be running even after the timeout.

o    Configuring Task Await Options:

•         await longTask.ConfigureAwait(false)
—  Configures the task to not need to return to the synchronization context it was originally invoked with. The context is usually the thread it was invoked on.
—  Lowers chance of deadlocks and should be preferred.

•         await longTask.ConfigureAwait(true)
—  Configures the task to need to return to the synchronization context it was originally invoked with. The context is usually the thread it was invoked on.
—  This is the default for awaited tasks without calling .ConfigureAwait().
—  Usually used when modifying UI elements that need to occur on the UI thread.

o    Function Definitions:

•         int Method()
—  Method can internally contain Tasks.
—  Method can internally .Wait() Tasks.
—  Method cannot internally await Tasks.
—  Method can return int.
—  Method cannot be awaited on externally.
—  Can externally catch exceptions thrown by Method.

•         Task<int> Method()
—  Method can internally contain Tasks.
—  Method can internally .Wait() Tasks.
—  Method cannot internally await Tasks.
—  Method can return Task<int>.
—  Method can be awaited on externally.
—  Can externally catch exceptions thrown by Method when awaited.

•         async Task<int> Method()
—  Method can internally contain Tasks.
—  Method can internally .Wait() Tasks.
—  Method can internally await Tasks.
—  Method can return int.
—  Method can be awaited on externally.
—  Can externally catch exceptions thrown by Method when awaited.

•         Task Method()
—  Method can internally contain Tasks.
—  Method can internally .Wait() Tasks.
—  Method cannot internally await Tasks.
—  Method can return Task.
—  Method can be awaited on externally.
—  Can externally catch exceptions thrown by Method when awaited.

•         async Task Method()
—  Method can internally contain Tasks.
—  Method can internally .Wait() Tasks.
—  Method can internally await Tasks.
—  Method cannot return anything.
—  Method can be awaited on externally.
—  Can externally catch exceptions thrown by Method when awaited.

•         async void Method()
—  Method can internally contain Tasks.
—  Method can internally .Wait() Tasks.
—  Method can internally await Tasks.
—  Method cannot return anything.
—  Method cannot be awaited on externally.
—  Cannot externally catch exceptions thrown by Method.
—  Usually used as an async event delegate function definition, any other situation should use async Task or async Task<T>.

Tuesday, August 6, 2013

First with Post and Purpose

      There comes a time when a learning goal's progress becomes too big to track solely with your mind. I seem to have hit this wall. So I am starting this blog to help track my progress. I feel writing will force me to reflect on the experiences. This reflection will serve to help solidify the knowledge. Hopefully others can benefit as well.  I hope we will both enjoy the journey together.