Async await

in C#

Why should we care?

  • Thundering herd
  • Horses = users

What is our goal

  • Do more with less
  • Juggle more users

How? An analogy

  • Imagine a 'wash and fold' laundry business
  • When people drop off clothes, you have a choice:
  • Sync vs async

Sync (blocking)

  • A customer arrives with clothes
  • You put the clothes in the machine
  • You sit in front of the machine until they are done
  • You take the clothes back to the front desk
  • You can now serve the next customer

Computer time

Async (non-blocking)

  • A customer arrives with clothes
  • You take their phone number and give them a ticket
  • You put the clothes in the machine
  • You go back to the desk to help the next customer
  • When the clothes are done, you call the first customer

Apply the analogy

  • Laundromat = your application
  • Customer = request
  • Employee = thread
  • Washing clothes = calling an external service
  • We want to be able to give people tickets, not sit and wait

Talk Outline

  • Key concepts
  • Best practices and common gotchas
  • 5 take aways

What is a task?

  • Think of a task like a laundry ticket
  • You give it to the customer immediately
  • When the items are ready, we'll tell you
  • "An abstraction over an activity that is ongoing and will eventually complete." Mads Torgersen

What is await?

  • Like the front desk
  • Place to come back when the task is done
  • Where we can resume execution for that customer
  • Await does not mean 'wait'

Waiting is relative

  • The customer still has to wait
  • But the employee does not
  • They can 'juggle' many customers

Is it faster?

  • The total washing time is still an hour
  • The user has to wait 1 hour plus service time
  • This is still faster than sync approach of a queue
  • In sync, your wait includes the washing time of other people

Threads

  • It's like the employee
  • One person can handle hundreds of customers because they do things concurrently
Parallel Concurrent
Literally at the same time Little slices, one after the other

Parallel vs concurrent

Multithreading Async await
Hire more employees Buy more washing machines
I/O CPU
Calling external service Internal work

I/O vs CPU

Async await helps here Parallelization helps here
Like the washing machine Like folding clothes
Calling DB, API, disk Looping, calculation

Summary (so far)

  • Task is like a ticket
  • Await is like the front desk
  • Thread is like an employee
  • We seem fast by doing this concurrently

Best practices

When I/O, then async

  • Any time we call an external service
  • E.g. file system, API, DB
  • Use async await

Don't block

  • Avoid methods like .Result() or .WaitAll() or .Wait()
  • These will force the thread to sit in front of the washing machine
  • This means async code will spread

Be suspicious of Task.Run

  • This moves the work to another thread
  • Like hiring another person
  • If it's I/O they are still blocked - they still sit and wait for machine to finish
  • Might be okay for CPU bound work but there are better ways to do parallelization 

Avoid await inside a loop

Use list of tasks instead

Use .ConfigureAwait(false) for UI thread

  • This allows ANY thread to resume the work, not the calling thread
  • This is important for any applications with a UI
  • Any laundromat employee can give your clothes back, not just the one who served you originally
  • Dotnet core does not have this problem

5 take aways

  • All I/O should be async
  • Avoid blocking keywords
  • Be suspicious of Task.Run
  • Avoid await inside a loop
  • Use .ConfigureAwait(false) for old UI work
Made with Slides.com