Async in C# - The Good, the Bad and the Ugly

A presentation at Various events in March 2019 in by Stuart Lang

Slide 1

Slide 1

Async in C# The good, the bad and the ugly πŸ˜‹πŸ˜’πŸ˜­

Slide 2

Slide 2

Hi, I’m Stu ◍ ◍ ◍ ◍ F# |> I ❀ 8 years of experience in .NET Organiser of Bristol F# meetup and DDD South West Passionate about Open Source You can find me at @stuartblang

Slide 3

Slide 3

Why an Async talk?

Slide 4

Slide 4

History of Async You are here! 2011 2018 Async/Await introduced .NET 4.5 C# 5

Slide 5

Slide 5

β€œ It really troubles me how much async, bad async, really bad async we see in the wild Kathleen Dollard - .NET Rocks! #1143

Slide 6

Slide 6

Async is an abstraction Safe Abstractions Dangerous Abstractions Async/Await β€œPowerful” Leaky Magic

Slide 7

Slide 7

The Good ◍ Non-blocking waiting ◍ There is no thread!

Slide 8

Slide 8

The Bad ◍ ◍ ◍ ◍ ◍ ◍ Not clear what is true async Minor performance overhead Duplicated code Async can’t go everywhere Risk of async deadlocks Doing it wrong is much worse that not doing it at all

Slide 9

Slide 9

How does it work? Compiler generated code

Slide 10

Slide 10

How does it work?

Slide 11

Slide 11

How does it work? True async Task.FromResult(…) Task.Run(() => …)

Slide 12

Slide 12

.ConfigureAwait(false) What’s that about?

Slide 13

Slide 13

Synchronization Context What’s that about?

Slide 14

Slide 14

How does it work?

Slide 15

Slide 15

Continuing on Captured Context

Slide 16

Slide 16

Synchronization Context Cont.

Slide 17

Slide 17

Synchronization Context Cont. WindowsFormsSynchronizationContext DispatcherSynchronizationContext Default (ThreadPool) SynchronizationContext AspNetSynchronizationContext

Slide 18

Slide 18

SynchronizationContext Behaviors Specific Thread Used to Execute Delegates Exclusive (Delegates Execute One at a Time) Ordered (Delegates Execute in Queue Order) Send May Invoke Delegate Directly Post May Invoke Delegate Directly WinForms Yes Yes Yes If called from UI thread Never WPF Yes Yes Yes If called from UI thread Never Default No No No Always Never ASP.NET No Yes No Always Always

Slide 19

Slide 19

Deadlock

Slide 20

Slide 20

Slide 21

Slide 21

KA-BLAMO!

Slide 22

Slide 22

Slide 23

Slide 23

Slide 24

Slide 24

KA-BLAMO!

Slide 25

Slide 25

Slide 26

Slide 26

Slide 27

Slide 27

ContextFreeTask

Slide 28

Slide 28

vs-threading

Slide 29

Slide 29

Formal definition of async deadlocks You are susceptible to deadlocks if: 1. 2. You have a current SynchronizationContext that enforces exclusive access; Some code further into your call stack has access to it and can/does: a. Synchronously block on some async code; b. Within that async code awaits an incomplete task that does not use .ConfigureAwait(false), or temporarily removes the context. If you use .Result, .Wait(), .GetAwaiter().GetResult() you have done a dangerous thing, and you should be prepared to guard against naughty awaiters (you may not even control).

Slide 30

Slide 30

Resources Prevention Methods ◍ ◍ ◍ ◍ ◍ ◍ ◍ ◍ .ConfigureAwait(false) all the things ContextFreeTask Comment the code null the SynchronizationContext (with handy helper functions) async top to bottom (replace our libraries and framework where we have to) Deadlock detection in QA & Prod Detect deadlocks in unit tests? Use ASP.NET Core! Automated Tools ◍ ◍ ◍ ◍ ◍ Microsoft’s AsyncPackage (Roslyn Analyzer) Async006 - Detects more blocking calls than you can shake a stick at. ConfigureAwait.Fody ConfigureAwait Checker for ReSharper ConfigureAwaitChecker - Roslyn Analyzer + VSIX DeadlockDetection

Slide 31

Slide 31

Awesome async resources ◍ Stephen Cleary β—Œ https://blog.stephencleary.com/ ◍ Anthony Steele β—Œ Avoiding basic mistakes in async await β—Œ Resynchronising async code

Slide 32

Slide 32

Async Guidance ◍ davidfowl/AspNetCoreDiagnosticScenarios - AsyncGuidance.md

Slide 33

Slide 33

οΏ½οΏ½ Thanks! Any questions? You can find me at @stuartblang & stuart.b.lang@gmail.com

Slide 34

Slide 34

οΏ½οΏ½ Thanks! Any questions? You can find me at @stuartblang & stuart.b.lang@gmail.com