by Oliver
28. November 2017 10:58
Disclaimer:
This is just a bunch of short notes I took during a conference session held by Daniel Marbach at the .NET Developer Days. To dive deeper into the topic, please head over to the following GitHub repo, run the examples, and examine the source code: https://github.com/danielmarbach/Await.HeadExplosion/tree/master/Presentation.
My take aways:
- use Task.Run() for compute-bound operations, avoid the low-level method Task.Factory.StartNew()
- in the async world, use await Task.Delay() instead of Thread.Sleep()
- since .NET Framework 4.6, there's a cached static instance Task.CompletedTask that can be used whereever you want to return a completed task – no allocation needed
- opt out of context capturing by calling .ConfigureAwait(false) – when the previous execution context is not needed for the continuation of the async task
- concurrency != parallelism:
- a lot of tasks can be handled by a single thread-pool thread concurrently – only one thread will be used
- tasks can be split across many threads to achieve parallelism – when desired/necessary
- use SemaphoreSlim to limit parallelism, e.g. to use only 3 threads at the most
- use ValueTask<T> for high performance code – wrapper for situation where either a Task is supposed to be executed or its return value is already available, e.g. cached
Happy asyncing!