Craig DunnDeveloper [email protected]@conceptdev
C# async awaitfor mobile
Mobile Apps
• Need responsive user interfaces• App features are o!en dependent on:
network access (images, web services)database functionality or I/Ocomplex processing on mobile CPUsany stuff that takes some time
• You want to run these on a different thread to keep the UI responsive... they should be ASYNCHRONOUS!
Fast!
Long running tasks!
Threads!
All
Responsive User Interfaces
Don’t designfor desktop
Responsive User InterfacesInstagram Don’t design for desktop
start upload (or here)
so this is FAST
user doesn’t notice here...
Responsive User InterfacesDon’t design for desktopInstagram
hit-and-hope
• DO things in the background
• DON’T block the UI thread
• DON’T make users feel like they’re waiting
Responsive User InterfacesDon’t design for desktop
DEMODEMO1) Download Html string2) Download Jpeg image3) Save to Storage4) Return Html length
Old-style callbacks
1) Download Html string2) Download Jpeg image3) Save to Photo Album
5) Error Handling4) Return Html length
6) InvokeOnMainThread
Callback Hell
Old-style callbacks
1) Download Html string2) Download Jpeg image3) Save to Photo Album
5) Error Handling4) Return Html length
6) InvokeOnMainThread
Callback Hell
Old-style callbacks
1) Download Html string2) Download Jpeg image3) Save to Photo Album
5) Error Handling4) Return Html length
6) InvokeOnMainThread
Callback Hell
1) Download Html string2) Download Jpeg image3) Save to Photo Album
5) Error Handling4) Return Html length
6) InvokeOnMainThread
Callback Hell
Old-style callbacks
What is “async”?
• Tasks running outside of the main program flow• Code runs on another thread, so the UI doesn’t block/freeze• Completion runs on the calling thread, so if you started on the
UI that’s where you’ll be a!er the async task is complete
• async and await syntax in C# 5 takes Task support to the next level!
Frameworks need to support it on long running tasks
Task Parallel Library (TPL) has been around a while
Old-style callbacks
• Spaghetti code:
Callbacks are the new “GOTO”Control flow jumps around in ways that are difficult to read & understand from the sourceError handling is difficult to implement, required in many different placesChanges in the chain can have unintended consequences
http://tirania.org/blog/archive/2013/Aug-15.html
Old-style callbacks
• Execute On Main ThreadWe need to schedule updates - can’t just access UI objects directly from background threadsDispatcher.Invoke (pre RT)
USING ASYNCasync, await, cancellation and error handling
Comparison
1) Download Html string2) Download Jpeg image3) Save to Photo Album
5) Error Handling4) Return Html length
6) InvokeOnMainThread
Callback Hell
Comparison
1) Download Html string2) Download Jpeg image3) Save to Photo Album
5) Error Handling4) Return Html length
6) InvokeOnMainThread
Callback Hell
1) Download Html string2) Download Jpeg image3) Save to Photo Album
5) Error Handling4) Return Html length
Comparison
Async-ified
6) InvokeOnMainThread
1) Download Html string2) Download Jpeg image3) Save to Photo Album
5) Error Handling4) Return Html length
Comparison
6) InvokeOnMainThreadone place
not required
Async-ified
Comparison
1) Download Html string2) Download Jpeg image3) Save to Photo Album
5) Error Handling4) Return Html length
6) InvokeOnMainThread
old new!
Compiler Magic
http://msdn.microso!.com/en-us/library/vstudio/hh191443.aspx
Compiler Magic• async keyword informs the compiler that this method needs to be
“munged”• await keyword indicates a suspension point where a callback
needs to be generated, along with error handling• Continuations are generated a!er each suspension point• Error handling (support for enclosing try-catch) is taken care of
• All you need to remember is async and awaitand use Tasks
How to use: async?• async modifier on methods, lambdas and anonymous methods
use Async suffix, eg LoadAsync, SendAsyncreturn Task or Task<T> preferably
- Task for methods that don’t return a value
- Task<T> to return a value
- void for event handlers only!
void for event handlers
How to use: await?• await keyword on awaitable objects (Tasks)
only within an async contextmarks a suspension point - control is returned to callercan’t be used in catch or finally blocksTask, Task<T> or a custom type
get a reference to the Task first
... or just await
How to use: error handling?• async Task or Task<T>
Returned Task State == FaultedException re-thrown when task is awaited
• async void methods (event handlers)Exception is thrown on the current synchronization context and the app will crash...
How to use: error handling?• “If a task is the parent of attached child tasks, or if you are
waiting on multiple tasks, then multiple exceptions could be thrown”
• AggregateExceptionLoop through, handle or throw as required...
• Cancellation is optionalusually exposed an Async() method overload that takes a CancellationToken parametercalling code uses the tokenCancellation.None means it won’t be cancelled by the caller (useful when the cancellation parameter isn’t optional)
How to use: cancellation?
• Cancellation is optionalcancelled async tasks complete (but time for this to happen isn’t guaranteed)
How to use: cancellation?
• Specifying a timeout is optionalfor HttpClient, set Timeout
some Async methods accept a timeout parameter
more generally, use CancellationToken (timeout)
How to use: timeouts?
• Progress reporting is optionalprovide another Async overload with an IProgress<T> parameterbasic Progress<T> implementation can be usedexposes EventHandler<T> ProgressChanged
How to use: progress reporting?
send events to track progress
BONUS: Combinators• Wait on multiple tasks
Task.WhenAll (IEnumerable<Task>)
- requires all the tasks to be completedTask.WhenAny(IEnumerable<Task>)
- returns when any of the tasks completes
this kind of loop fine for small numbersof Tasks
WARNING: Await, and UI, and deadlocks
http://blogs.msdn.com/b/pfxteam/archive/2011/01/13/10115163.aspx
MOAR MOBILEiOS & Android too!
.NET BCL APIs
• Lots of .NET APIs support async; for example:HttpClient.GetStringAsync()HttpClient.PostAsync()FileStream.ReadAsync()FileStream.CopyToAsync()
• and many more...
Windows Store and Phone appsonly have async APIs
Xamarin.iOS
• updated iOS APIs to be async; some examples:ALAssetsLibrary.WriteImageToSavedPhotosAlbumAsync()ALAsset.SetImageDataAsync()SKStoreProductViewController.LoadProductAsync()CLGeocoder.GeocodeAddress()NSUrlConnection.SendRequestAsync()
and many more... 174 async iOS native APIs
Xamarin.Android
• updated Android APIs to be async; some examples:Android.Net.Http.AndroidHttpClient.ExecuteAsync()Android.Bluetooth.BluetoothServerSocket.AcceptAsync()Android.Graphics.BitmapFactory.DecodeFileAsync()Android.Locations.Geocoder.GetFromLocationAsync()Java.IO.File.ListAsync()
and many more... 337 async Android native APIs
Xamarin APIs
• Xamarin.Mobile Geolocator.GetPositionAsync()Contact.SaveThumbnailAsync()
• Xamarin.Auth
FormAuthenticator.SignInAsync()Request.GetResponseAsync(cancellationToken)
• and many more...Xamarin cross-platform libraries
Xamarin Component Store
• Many components already offer async APIs, eg. Parse!
Powerful, easy to use componentshttp://components.xamarin.com
DEMODEMOParseTodo
Other tricks...• Creating your own async Tasks
eg. how you could async-ify WebClient
http://developer.nokia.com/Community/Wiki/Asynchronous_Programming_For_Windows_Phone_8
Other tricks...
• Creating your own async Tasks
Don’t await... give it a try• Available in .NET 4.5 for Windows Store apps, Windows 8,
Windows Phone, etc.
• Also available programming in C# iOS & Android using Xamarin!
xamarin.com/download
Questions?Developer [email protected]@conceptdev
Craig Dunn