await Xamarin @ PTXug
-
Upload
paulo-morgado -
Category
Technology
-
view
192 -
download
0
Transcript of await Xamarin @ PTXug
![Page 1: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/1.jpg)
Lisbon, May 30th 2015
await Xamarin()PTXug - Xamarin Talks #1
![Page 2: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/2.jpg)
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: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/3.jpg)
async-await best practices
Agenda
![Page 4: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/4.jpg)
For goodness’ sake, stop using async void!
![Page 5: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/5.jpg)
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: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/6.jpg)
Events are not going away.
![Page 7: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/7.jpg)
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: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/8.jpg)
Is it CPU-bound,or I/O-bound?
![Page 9: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/9.jpg)
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: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/10.jpg)
Don’t lie
![Page 11: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/11.jpg)
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: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/12.jpg)
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: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/13.jpg)
Libraries shouldn’t use Task.Run()
![Page 14: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/14.jpg)
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: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/15.jpg)
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: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/16.jpg)
Task.Run() is the way to create new tasks
![Page 17: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/17.jpg)
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: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/18.jpg)
await all the way
![Page 19: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/19.jpg)
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: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/20.jpg)
Use ConfigureAwait(fals
e)
![Page 21: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/21.jpg)
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: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/22.jpg)
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: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/23.jpg)
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: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/24.jpg)
Use the CancellationToken
![Page 25: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/25.jpg)
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: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/26.jpg)
Cache the returned Task<T>
![Page 27: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/27.jpg)
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: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/28.jpg)
Q & A
![Page 29: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/29.jpg)
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: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/30.jpg)
Sponsors
![Page 31: await Xamarin @ PTXug](https://reader038.fdocuments.us/reader038/viewer/2022110123/55b9c54abb61ebd0078b479f/html5/thumbnails/31.jpg)
THANK YOU !C:\> ping me
@paulomorgado