using async in your mobile apps - marek safar

30
Marek Safar Engineer Xamarin [email protected] Using Async in Your Apps

Upload: xamarin

Post on 20-Jan-2015

1.467 views

Category:

Technology


0 download

DESCRIPTION

 

TRANSCRIPT

Page 2: Using Async in your Mobile Apps - Marek Safar

You?

Page 3: Using Async in your Mobile Apps - Marek Safar

Wikipedia

“Asynchronous events are those occurring independently of the main program flow. Asynchronous actions are actions executed in a non-blocking scheme, allowing the main program flow to continue processing”

Page 4: Using Async in your Mobile Apps - Marek Safar

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

Page 5: Using Async in your Mobile Apps - Marek Safar
Page 6: Using Async in your Mobile Apps - Marek Safar

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 be

asynchronous• New contextual keyword await introduced

Page 7: Using Async in your Mobile Apps - Marek Safar

Adding Async to Your Codebase

• Decorated with new async modifier• Async method must return one of

Task, 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>)

Page 8: Using Async in your Mobile Apps - Marek Safar

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

Example: Calculating a Price Asynchronously public  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};

}

Page 9: Using Async in your Mobile Apps - Marek Safar

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 any custom type)As many as you like inside async block

Page 10: Using Async in your Mobile Apps - Marek Safar

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

Calculating a Price Asynchronously public  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  ();

};}

Page 11: Using Async in your Mobile Apps - Marek Safar

Cancelling an Async Task

• CancellationToken controls cancellation process• Async method needs explicitly support it

Usually 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

Page 12: Using Async in your Mobile Apps - Marek Safar

DEMO

Page 13: Using Async in your Mobile Apps - Marek Safar

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

Async 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  ()  };...

}

Page 14: Using Async in your Mobile Apps - Marek Safar

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

Page 15: Using Async in your Mobile Apps - Marek Safar

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 suspended context

SynchronizationContext::Post method is usedSuspension on UI thread resumes back on same UI thread as “expected”

Page 16: Using Async in your Mobile Apps - Marek Safar

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 your app will crash

Page 17: Using Async in your Mobile Apps - Marek Safar

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

Exception 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;

}};

}

Page 18: Using Async in your Mobile Apps - Marek Safar

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

Exception 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");

}...

}

Page 19: Using Async in your Mobile Apps - Marek Safar

Diving Deeper

• Await can work with any type which implements the awaiter pattern

• Task and Task<T> types do since .NET 4.5• Any custom type can be made awaitable

Has an accessible method called GetAwaiter returning a type whichImplements the interface INotifyCompletionHas property IsCompleted of type boolHas method GetResult with no parameters

Page 20: Using Async in your Mobile Apps - Marek Safar

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

Custom 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  ();}

Page 21: Using Async in your Mobile Apps - Marek Safar

Async Deadlocks

• await restores execution context based on current SynchronizationContext

Good for most application codeBad for most library code

• Don’t block the UI threadGood old rule still applies in async worldUse await when possible

Page 22: Using Async in your Mobile Apps - Marek Safar

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

Async 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

}

Page 23: Using Async in your Mobile Apps - Marek Safar

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

Page 24: Using Async in your Mobile Apps - Marek Safar

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

Async 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

}

Page 25: Using Async in your Mobile Apps - Marek Safar

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

Page 26: Using Async in your Mobile Apps - Marek Safar

The Compiler Magic

• Compiler does all the “magic”• Local variable and parameters are li!ed into compiler generated

typeCompiler 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

Page 27: Using Async in your Mobile Apps - Marek Safar

Best Practices - Performance

• Use ConfigureAwait when you can• Reduce number of local variables

Move async block into separate method or lambda expressionPass variables as parametersAvoid deep await usage

• Cache Task not task result• Don’t over use async

Use async only when appropriate (unreliable tasks, running >50ms)Async has its own overhead

Page 28: Using Async in your Mobile Apps - Marek Safar

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

Page 29: Using Async in your Mobile Apps - Marek Safar

Q&A

Page 30: Using Async in your Mobile Apps - Marek Safar

THANK YOU