31
Lisbon, May 30 th 2015 await Xamarin() PTXug - Xamarin Talks #1

PTXug - Await/Async - Talks #1

  • Upload
    ptxug

  • View
    40

  • Download
    0

Embed Size (px)

Citation preview

Page 1: PTXug - Await/Async - Talks #1

Lisbon, May 30th 2015

await Xamarin()PTXug - Xamarin Talks #1

Page 2: PTXug - Await/Async - Talks #1

Speaker

http://PauloMorgado.NET/http://about.me/PauloMorgadohttp://www.slideshare.net/PauloJorgeMorgadohttp://pontonetpt.org/blogs/paulomorgado/http://blogs.msmvps.com/paulomorgado/http://weblogs.asp.net/paulomorgadohttp://www.revista-programar.info/author/pmorgado/

C:\> ping me @paulomorgado

Page 3: PTXug - Await/Async - Talks #1

async-await best practices

Agenda

Page 4: PTXug - Await/Async - Talks #1

For goodness’ sake, stop using async void!

Page 5: PTXug - Await/Async - Talks #1

async void is only for event handlers

PrinciplesAsync void is a “fire-and-forget” mechanism...The caller is unable to know when an async void has finishedThe caller is unable to catch exceptions thrown from an async void

(instead they get posted to the UI message-loop)

GuidanceUse async void methods only for top-level event handlers (and their like)Use async Task-returning methods everywhere elseIf you need fire-and-forget elsewhere, indicate it explicitly e.g. “FredAsync().FireAndForget()”When you see an async lambda, verify it

Page 6: PTXug - Await/Async - Talks #1

Events are not going away.

Page 7: PTXug - Await/Async - Talks #1

async over events

PrinciplesCallback-based programming, as with events, is hard

GuidanceIf the event-handlers are largely independent, then leave them as eventsBut if they look like a state-machine, then await is sometimes easierTo turn events into awaitable Tasks, use TaskCompletionSource

Page 8: PTXug - Await/Async - Talks #1

Is it CPU-bound,or I/O-bound?

Page 9: PTXug - Await/Async - Talks #1

Thread pool

PrinciplesCPU-bound work means things like: LINQ-over-objects, or big iterations, or computational inner loops.Parallel.ForEach and Task.Run are a good way to put CPU-bound work onto the thread pool.Thread pool will gradually feel out how many threads are needed to make best progress.Use of threads will never increase throughput on a machine that’s under load.

GuidanceFor IO-bound “work”, use await rather than background threads.For CPU-bound work, consider using background threads via Parallel.ForEach or Task.Run, unless you're writing a library, or scalable server-side code.

Page 10: PTXug - Await/Async - Talks #1

Don’t lie

Page 11: PTXug - Await/Async - Talks #1

Two ways of thinking about asynchrony

Foo();Perform something here and now.I’ll regain control to execute something else when it’s done.

var task = FooAsync();Initiate something here and now.I’ll regain control to execute something else “immediately”.

From the method signature (how people call it)

Uses a CPU core solidly while it runs

void Foo(){ for (int i=0; i<100; i++) Math.Sin(i);}

From the method implementation (what resources it uses) Hardly touches the CPU

async Task FooAsync(){ await client.DownloadAsync();}

Page 12: PTXug - Await/Async - Talks #1

Async methods: Your caller’s assumptions

“This method’s name ends with ‘Async’, so…”

“…calling it won’t spawn new threads in my server app”

“…I can parallelize by simply calling it multiple times”

Is this true for your async methods?

Page 13: PTXug - Await/Async - Talks #1

Libraries shouldn’t use Task.Run()

Page 14: PTXug - Await/Async - Talks #1

Your callers should be the ones to call Task.Run

The thread pool is an app-global resourceThe number of threads available to service work items varies greatly over the life of an appThe thread pool adds and removes threads using a hill climbing algorithm that adjusts slowly

In a server app, spinning up threads hurts scalability

A high-traffic server app may choose to optimize for scalability over latencyAn API that launches new threads unexpectedly can cause hard-to-diagnose scalability bottlenecks

The app is in the best position to manage its threads

Provide synchronous methods that block the current threadProvide asynchronous methods when you can do so without spawning new threadsLet the app that called you use its domain knowledge to manage its threading strategy!

Page 15: PTXug - Await/Async - Talks #1

Sync methods: Your caller’s assumptions

“There’s a synchronous version of this method…”

“…I guess it must be faster than the async version”

“…I can call it from the UI thread if the latency’s fine”

void Foo() { FooAsync().Wait(); } -- will deadlock!!!

Page 16: PTXug - Await/Async - Talks #1

Task.Run() is the way to create new tasks

Page 17: PTXug - Await/Async - Talks #1

Task creation

PrinciplesTask.Run returns hot tasks (running or completed) created with settings suited to async-await.

GuidanceDon’t use Task.Factory.StartNew or the Task (or Task<T>) constructor.

Page 18: PTXug - Await/Async - Talks #1

await all the way

Page 19: PTXug - Await/Async - Talks #1

await all the way

PrinciplesThe compiler provides, through the await keyword, sequential execution of the code.

GuidanceDon’t mix async-await with ContinuesWith.

Page 20: PTXug - Await/Async - Talks #1

Use ConfigureAwait(fals

e)

Page 21: PTXug - Await/Async - Talks #1

SynchronizationContext

Represents a target for work via its Post methodWindowsFormsSynchronizationContext

.Post() does Control.BeginInvoke

DispatcherSynchronizationContext.Post() does Dispatcher.BeginInvoke

AspNetSynchronizationContext.Post() ensures one-at-a-time

… // ~10 in .NET Framework, and you can write your own… // Is the core way for “await” to know how to put you back

Page 22: PTXug - Await/Async - Talks #1

SynchronizationContext and await

“await task;”Captures the current SyncContext before awaiting.When it resumes, uses SyncContext.Post() to resume “in the same place”(If SyncContext is null, uses the TaskScheduler)

For application-level code:This behavior is almost always what you want.

For library-level code:This behavior is rarely what you want!

Page 23: PTXug - Await/Async - Talks #1

SynchronizationContext: ConfigureAwait

Task.ConfigureAwait(bool continueOnCapturedContext)

await t.ConfigureAwait(true) // defaultPost continuation back to the current context/scheduler

await t.ConfigureAwait(false)If possible, continue executing where awaited task completes

ImplicationsPerformance (avoids unnecessary thread marshaling)Deadlock (code shouldn’t block UI thread, but avoids deadlocks if it does)

Page 24: PTXug - Await/Async - Talks #1

Use the CancellationToken

Page 25: PTXug - Await/Async - Talks #1

Use the CancellationToken

PrinciplesThe CancellationToken structure is the way to signal and handle cancellation.

GuidanceIf you want your API to be cancellable, use cancellation tokens.If your code uses APIs that use cancellation tokens, use them.Always check the cancellation tokens.

Page 26: PTXug - Await/Async - Talks #1

Cache the returned Task<T>

Page 27: PTXug - Await/Async - Talks #1

Library perf considerations

PrinciplesAsync methods are faster than what you could write manually, but still slower than synchronous.The chief cost is in memory allocation (actually, in garbage collection).The "fast path" bypasses some allocations.

GuidanceAvoid designing "chatty" APIs where async methods are called in an inner loop; make them "chunky".If necessary, cache the returned Task object (even with cache size "1"), for zero allocations per call.As always, don't prematurely optimize!

Page 28: PTXug - Await/Async - Talks #1

Q & A

Page 29: PTXug - Await/Async - Talks #1

References

Talk: Async best practiceshttp://blogs.msdn.com/b/lucian/archive/2013/11/23/talk-mvp-summit-async-best-practices.aspx

Six Essential Tips For Async – Introductionhttp://channel9.msdn.com/Series/Three-Essential-Tips-for-Async/Three-Essential-Tips-For-Async-Introduction

Curah! async-await Generalhttp://curah.microsoft.com/45553/asyncawait-general

Curah! async-await and ASP.NEThttp://curah.microsoft.com/44400/async-and-aspnet

Xamarin Store Apphttps://github.com/paulomorgado/xamarin-xamarin-store-app

Page 30: PTXug - Await/Async - Talks #1

Sponsors

Page 31: PTXug - Await/Async - Talks #1

THANK YOU !C:\> ping me

@paulomorgado