Using Async in your Mobile Apps - Marek Safar

3,848 views

Published on

Published in: Technology, Education
1 Comment
3 Likes
Statistics
Notes
No Downloads
Views
Total views
3,848
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
45
Comments
1
Likes
3
Embeds 0
No embeds

No notes for slide

Using Async in your Mobile Apps - Marek Safar

  1. 1. Marek SafarEngineerXamarinmsafar@xamarin.comUsing Async in Your Apps
  2. 2. You?
  3. 3. Wikipedia“Asynchronous events are those occurring independentlyof the main program flow. Asynchronous actions areactions executed in a non-blocking scheme, allowing themain program flow to continue processing”
  4. 4. You Should Use Async Today• Your UI always remains responsive• No need to guard against race conditions• No ugly callbacks• Compiler does all the heavy li!ing
  5. 5. Async in C#• New major feature of C# 5.0Makes asynchronous programming a first-class citizen in C#Important part of C# – as significant as LINQ• New async modifier keyword introduced• Methods, lambda expressions, and anonymous methods can beasynchronous• New contextual keyword await introduced
  6. 6. Adding Async to Your Codebase• Decorated with new async modifier• Async method must return one ofTask, Task<T> or void type• Async anonymous method and lambdasDelegates returning Task, Task<T> or void• Very few restrictionsNo ref or out parameters allowedNo unsafe codeNo Main async methodNo async iterators (aka IAsyncEnumerable<T>)
  7. 7. 01020304050607080910111213141516Example: Calculating a Price Asynchronouslypublic  async  Task<int>  CalculatePriceAsync  (Item[]  items){int  price;//  Calculate  price  asynchronously  and  return  the  valuereturn  price;}public  override  void  ViewDidLoad  (){button.TouchDown  +=  async  (sender,  e)  =>  {//  This  is  asynchronous  handler};}
  8. 8. Await Introduction• Await can be used in async context onlyMarks a suspension pointCan be used anywhere (except catch and finally blocks)Requires awaitable types (Task, Task<T> but can be anycustom type)As many as you like inside async block
  9. 9. 01020304050607080910111213141516Calculating a Price Asynchronouslypublic  async  Task<int>  CalculatePriceAsync  (Item[]  items){using  (var  cmd  =  CreateSqlCommand  (Calculations.TotalPrice,  items))  {using  (var  reader  =  await  cmd.ExecuteReaderAsync  ())  {int  price  =  ReadPrice  (reader);return  price;}}}public  override  void  ViewDidLoad  (){button.TouchDown  +=  async  (sender,  e)  =>  {var  price  =  await  CalculatePriceAsync  (items);priceLabel.Text  =  price.ToString  ();};}
  10. 10. Cancelling an Async Task• CancellationToken controls cancellation process• Async method needs explicitly support itUsually another method overloadTask SaveAsync (CancellationToken token)• Caller calls Cancel on CancellationTokenSourceAsync method stops and returns Task with cancelled stateImplementation detail how quickly async method terminates
  11. 11. DEMO
  12. 12. 01020304050607080910111213141516Async Language Featurespublic  async  Task  RealAsync  (){//  This  is  real  async  heavy  code  (only  7  awaits  someone  else  will//  certainly  do  better)var  test  =  new  TestClass  (await  CallAsync  ()  |  await  CallAsync  ())  {   Latitude  =  await  GetLatitudeAsync  (await  AnotherAsync  ()),   Roles  =  from  role  in  await  GetRolesAsync  ()  where  role  ==  "agent"  select  role};....test  [await  CallAsync  ()]  =  new  int[]  {  33,  await  GetIntAsync  ()  };...}
  13. 13. Best Practices• Use Async naming suffix for asynchronous methodsLoadAsync, SendAsync, etc.Only recommended naming convention• Return Task or Task<T> preferablyTask for SaveAsync like methodsTask<T> for ReadAsync like methodsLeave async void to event handlers only• Support cancellation, if possible
  14. 14. Synchronization Context• Framework abstraction over UI toolkit threading modelNSRunLoop, DispatchContext in Xamarin.iOSMainLooper in Xamarin.AndroidDispatcher in WPFetc.• Await uses synchronization context to restore back suspendedcontextSynchronizationContext::Post method is usedSuspension on UI thread resumes back on same UI thread as“expected”
  15. 15. Sometimes Things Go Wrong• Async returning Task or Task<T>Task state is set to FaultedException is re-thrown when Task is checked (awaited)• Async voidFire and forget asynchronyException is thrown on current synchronization context and yourapp will crash
  16. 16. 01020304050607080910111213141516Exception Handling with Awaitpublic  override  void  ViewDidLoad  (){button.TouchDown  +=  async  (sender,  e)  =>  {try  {button.Enabled  =  false;var  price  =  await  CalculatePriceAsync  (items);priceLabel.Text  =  price.ToString  ();}  catch  (Exception  ex)  {//  Handles  price  calculation  errorpriceLabel.Text  =  "Calculation  failed";Debug.Print  (ex.ToString  ());  //  Simple  exception  logging}  finally  {button.Enabled  =  true;}};}
  17. 17. 01020304050607080910111213141516Exception Throwingpublic  async  Task<int>  CalculatePriceAsync  (Item[]  items){if  (items  ==  null)  {//  Throw  before  suspensionthrow  new  ArgumentNullException  ("items");}...var  price  =  await  CalculatePriceAsync  (items);if  (price  <  0)  {//  Throw  after  suspensionthrow  new  ArgumentException  ("Invalid  items");}...}
  18. 18. Diving Deeper• Await can work with any type which implements the awaiterpattern• Task and Task<T> types do since .NET 4.5• Any custom type can be made awaitableHas an accessible method called GetAwaiter returning a type whichImplements the interface INotifyCompletionHas property IsCompleted of type boolHas method GetResult with no parameters
  19. 19. 01020304050607080910111213141516Custom await Behaviourpublic  async  Task<int>  SomeAsync  (){    ...    await  3000;  //  This  does  not  compile  unless  we  provide  custom  awaiter    ...}//  Name  of  the  method  is  importantstatic  TaskAwaiter  GetAwaiter  (this  int  millisecondsDelay){    return  Task.Delay  (millisecondsDelay).GetAwaiter  ();}
  20. 20. Async Deadlocks• await restores execution context based on currentSynchronizationContextGood for most application codeBad for most library code• Don’t block the UI threadGood old rule still applies in async worldUse await when possible
  21. 21. 01020304050607080910111213141516Async Deadlock Examplepublic  async  Task<int>  CalculatePriceAsync  (Item[]  items){using  (var  cmd  =  CreateSqlCommand  (Calculations.TotalPrice,  items))  {using  (var  r  =  await  cmd.ExecuteReaderAsync  ())  {.....}}}//  The  method  itself  cannot  be  asyncpublic  override  bool  FinishedLaunching  (UIApplication  app,  NSDictionary  options){....int  price  =  CalculatePriceAsync  (items).Result;    //  Synchronous  wait//  This  line  won’t  be  reached  if  flow  suspension  occurred}
  22. 22. Controlling the Synchronization Context• ConfigureAwait (bool)Controls captured context behaviour• true value - default behaviourContinue execution on context async was called fromImportant for UI to switch back to UI context• false valueAvoids expensive context switchingAvoids possible deadlocks on blocking UI
  23. 23. 01020304050607080910111213141516Async Deadlock Fixedpublic  async  Task<int>  CalculatePriceAsync  (Item[]  items){using  (var  cmd  =  CreateSqlCommand  (Calculations.TotalPrice,  items))  {using  (var  r  =  await  cmd.ExecuteReaderAsync  ().ConfigureAwait  (false))  {//  The  context  is  not  restored  but  that’s  fine  for  no  UI  method  }}}//  The  method  itself  cannot  be  asyncpublic  override  bool  FinishedLaunching  (UIApplication  app,  NSDictionary  options){....int  price  =  CalculatePriceAsync  (items).Result;    //  Synchronous  wait//  Program  continues  when  the  wait  is  signalled}
  24. 24. Combinators• Asynchronously wait on multiple asynchronous operationsBetter than individual awaits of multiple tasksThe result can be awaited (Task of Tasks)• Task.WhenAll (IEnumerable<Task>)Completes when all of the individual tasks have completed• Task.WhenAny (IEnumerable<Task>)Completes when any of the individual tasks have completed
  25. 25. The Compiler Magic• Compiler does all the “magic”• Local variable and parameters are li!ed into compiler generatedtypeCompiler converts variables and parameters to fields• Any stack values need to be li!ed tooStack needs to be restored a"er suspension• Try-Catch block over any async block• No suspension when awaited task finished
  26. 26. Best Practices - Performance• Use ConfigureAwait when you can• Reduce number of local variablesMove async block into separate method or lambda expressionPass variables as parametersAvoid deep await usage• Cache Task not task result• Don’t over use asyncUse async only when appropriate (unreliable tasks, running >50ms)Async has its own overhead
  27. 27. Get Your Hands on Async• Async is available todayXamarin.iOS Beta releaseXamarin.Android Beta releaseXamarin Studio async support• Give us feedback on our new async APIForumsBugzillaMailing listIRC
  28. 28. Q&A
  29. 29. THANK YOU

×