+ All Categories
Home > Documents > DEV415. You are in a dark room with no signs of life. You still have your torch and $356. You can go...

DEV415. You are in a dark room with no signs of life. You still have your torch and $356. You can go...

Date post: 16-Dec-2015
Category:
Upload: ashley-johnston
View: 215 times
Download: 0 times
Share this document with a friend
Popular Tags:
37
The conjurer's masterpiece Hiding complexity with async Mark Young Datacom [email protected] DEV415
Transcript

The conjurer's masterpieceHiding complexity with async

Mark YoungDatacom

[email protected]

DEV415

“I love magic, as long as I understand how it works”

- Jon Skeet, 2013

“Any sufficiently advanced technology is indistinguishable

from magic”- Arthur C. Clarke, 1961

TodayOverviewWhy do we need asynchronous programming?Async in C#

Let’s build itWhy not?

Practical async6 tips you should know

What is asynchrony?And why do we need it?

You are in a dark room with no signs of life. You still have your torch and $356.

You can go North (N) or South (S).

Your choice? _

Modern development requires multiple processes to be happening simultaneously…

…but we don’t always like the resulting code

Asynchronous programming involves the coordination of multiple concurrent processes

Approach 1: Blockingvoid ServeCustomer(Customer customer){ var order = TakeOrder(customer);

// blocking call var pizza = GetSomeoneToMakeThePizza(order);

GivePizzaToCustomer(customer, pizza); WaitForCustomerToFinishEating();

CleanUpCustomerRubbish();}

Blocking can be dangerousWhen we have scarce resources (threads)UI threadsJavascriptI/O

When resources are too expensive~1MB per thread memory usageThreads are only added to the ThreadPool slowly

When we have too many processes to coordinate‘Duplex’ connections – long running process per user

Approach 2: Callbacksvoid ServeCustomer(Customer customer){ var order = TakeOrder(customer);

var cook = new Cook(); cook.PizzaFinished += (pizza) => { customer.FinishedEating += CleanUpCustomerRubbish;

GivePizzaToCustomer(customer, pizza); };

cook.GetSomeoneToMakeThePizza(order); // How do we return a value from the method?}

Approach 3: Promisesvoid ServeCustomer(Customer customer){ var order = TakeOrder(customer);

GetSomeoneToMakeThePizza(order) .ContinueWith(pizzaTask => { GivePizzaToCustomer(customer, pizza); return WaitForCustomerToFinishEating(); }) .ContinueWith(task => { CleanUpCustomerRubbish(); });}

C# async awaitasync void ServeCustomer(Customer customer){ var order = TakeOrder(customer);

var pizza = await GetSomeoneToMakeThePizza(order);

GivePizzaToCustomer(customer, pizza); await WaitForCustomerToFinishEating();

CleanUpCustomerRubbish();}

C# async awaitasync void ServeCustomer(Customer customer){ var order = TakeOrder(customer);  try { var pizza = await GetSomeoneToMakeThePizza(order); GivePizzaToCustomer(customer, pizza);  using (var employee = GetNewEmployee()) { await WaitForCustomerToFinishEating();  employee.CleanUpCustomerRubbish(); } } catch (PizzaMakingException ex) {  }}

Building async

Let’s see how it works

Task PlayersTasksThe results or promise of a result from asynchronous methods

AwaitersHolds a collection of continuations, TaskAdapter<T> acts as adapter for a Task<T>

MethodBuilderCoordinates the running of an async method

ContinuationsWhat do I run when the task is finished?

SchedulersHow do I run the continuation?

Practical async in C#6 things to know

Use TaskCompletionSource to create your own Tasks Task<Pizza> CookPizzaAsync(Order order){ var taskCompletion = new TaskCompletionSource<Pizza>();

var cook = new Cook(); cook.PizzaCompleted += (pizza) => { taskCompletion.SetResult(pizza); };

cook.MakePizza(order);

return taskCompletion.Task;}

Wrap business process in Tasks

async Task SpeakAtTechEd(){ SubmitTopics();

var acceptedTalks = await WaitToHearIfAcceptedAsync(); var slides = await Task.WhenAll( acceptedTalks.Select( talk => PrepareTalkAsync(talk) ) );

DeliverTalks(slides);}

Make sure all Tasks are observed

void OnButtonClick(){ var customer = MeetNewCustomer(); // don’t do this. Make ServeCustomerAsync async void, or await it ServeCustomerAsync(customer);}

async Task ServeCustomerAsync(Customer customer){ ...}

Be careful with async void

void OnButtonClick(){ var customer = MeetNewCustomer(); ServeCustomerAsync(customer);

// Customers may or may not still be eating… and we can’t catch Exceptions WashDishes();}

async void ServeCustomerAsync(Customer customer){ ...}

Use ConfigureAwait(false) when possible

async Task PushDataAsync(){ var customer = await GetCustomerAsync() .ConfigureAwait(false);

await UpdateDatabaseAsync() .ConfigureAwait(false);

await PushDataToServiceAsync() .ConfigureAwait(false);}

Async void can still be unit tested

[TestMethod]public async Task SimpleAsyncVoidExample(){ var customer = new Customer(); // async void methods UpdateFirstName(customer); UpdateLastName(customer);  // Override the SynchronizationContext // Utilise the OperationStarted and OperationCompleted overrides await TaskTrackingSynchronizationContext.WaitForAsync();  Assert.AreEqual("Bob", customer.FirstName); Assert.AreEqual("Jones", customer.LastName);}

 

 

What’s new in VS 2013?

Simplified debugging

So….

Go code better with asyncAnd enjoy the magic

Questions?

Related contentBreakout Sessions

DEV414: Taming Time: A Deep Dive into the Reactive Extensions

Linkshttp://blogs.msdn.com/b/pfxteam/http://msmvps.com/blogs/jon_skeet/archive/tags/Eduasync/default.aspx

Contact me later…During drinksTwitter: @kiwidevEmail: [email protected]

Evaluate this session and you could win instantly!

Head to...aka.ms/te

© 2013 Microsoft Corporation. All rights reserved.Microsoft, Windows and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.

Async comes in many flavours.NET 4.5.NET 4 (with BCL.Core.Async)PCLXamarin

Javascript (ES6 generators)Currently in Firefox and node.js

Yieldvoid CallYield(){ int callIndex = 0; Console.WriteLine(“ Call - 1"); foreach (var number in GetNumbers()) { Console.WriteLine(" Call: " + callIndex++); }}

IEnumerable<int> GetNumbers(){ Console.WriteLine("Before 1"); yield return 1;

Console.WriteLine("Before 2"); yield return 2;

Console.WriteLine("Yield finished");}

Call - 1Before 1 Call: 0Before 2 Call: 1Yield finished Call: 2


Recommended