Asynchronous programming Deadlock All The Things!.

19
Asynchronous programming Deadlock All The Things!

Transcript of Asynchronous programming Deadlock All The Things!.

Page 1: Asynchronous programming Deadlock All The Things!.

Asynchronous programming

Deadlock All The Things!

Page 2: Asynchronous programming Deadlock All The Things!.

/ Copyright ©2014 by Readify Pty Ltd2Page

Filip [email protected]

http://fekberg.com

+61 (401) 157-608

@fekberg

C# Smorgasbord

Page 3: Asynchronous programming Deadlock All The Things!.

Page / Copyright ©2014 by Readify Pty Ltd3

Asynchronous programming?› Processing allowed before current execution is done, such as read/write to disk

› So is this the same as parallel? Not quite.

@fekberg

Page 4: Asynchronous programming Deadlock All The Things!.

Page / Copyright ©2014 by Readify Pty Ltd4

Async + Parallel12:38

Load app content

Sort data

Process

records

Asynchronous task

@fekberg

Page 5: Asynchronous programming Deadlock All The Things!.

Page / Copyright ©2014 by Readify Pty Ltd5

Async? Never heard of it.› Ajax - Asynchronous JavaScript and XML› Request data› Handle the response when available

@fekberg

Page 6: Asynchronous programming Deadlock All The Things!.

Page / Copyright ©2014 by Readify Pty Ltd6

Introducing Async and Await› Two new Contextual Keywords as of .NET 4.5

› Meaning it does all the hard work for you

public async Task RunAsync(){ await Task.Run(() => { });}

@fekberg

Page 7: Asynchronous programming Deadlock All The Things!.

Page / Copyright ©2014 by Readify Pty Ltd7

Marking a method as Async› This will indicate that the method will be executed from within a state machine

› Adds overhead

› If it is not actually awaiting something, don’t mark it as async!

› Simply marking as async doesn’t make it async!

@fekberg

Page 8: Asynchronous programming Deadlock All The Things!.

Page / Copyright ©2014 by Readify Pty Ltd8

What do you think happens?private void Button_Click(){ try { Run(); } catch (Exception ex) { }}

public void Run(){ throw new Exception();}

@fekberg

Page 9: Asynchronous programming Deadlock All The Things!.

Page / Copyright ©2014 by Readify Pty Ltd9

What do you think happens?private void Button_Click(){ try { RunAsync(); } catch (Exception ex) { }}

public async void RunAsync(){ throw new Exception();}

@fekberg

Page 10: Asynchronous programming Deadlock All The Things!.

Page / Copyright ©2014 by Readify Pty Ltd10

The second one crashes!› Async void is EVIL!

› Marking a method as async wraps it inside a state machine[AsyncStateMachine(typeof(<RunAsync2>d__0)), DebuggerStepThrough]public void RunAsync2(){ <RunAsync2>d__0 d__; d__.<>4__this = this; d__.<>t__builder = AsyncVoidMethodBuilder.Create(); d__.<>1__state = -1; d__.<>t__builder.Start<<RunAsync2>d__0>(ref d__);}

@fekberg

Page 11: Asynchronous programming Deadlock All The Things!.

Page / Copyright ©2014 by Readify Pty Ltd11

How do we handle this?› Use Task as a return type instead

› Always await your async callsprivate async void Button_Click(){ try { await RunAsync(); } catch (Exception ex) { }}

private void Button_Click(){ RunAsync();}

public async Task RunAsync(){ throw new Exception();}

Silently fails

“Validates” and lets you catch any possible exceptions

@fekberg

Page 12: Asynchronous programming Deadlock All The Things!.

Page / Copyright ©2014 by Readify Pty Ltd12

Proper Async methodpublic async Task BoilEggsAsync(int amountOfEggs){ await BoilAsync(amountOfEggs); }

public Task BoilEggsAsync(int amountOfEggs){ <BoilEggsAsync>d__5 d__; d__.<>4__this = this; d__.amountOfEggs = amountOfEggs; d__.<>t__builder = AsyncTaskMethodBuilder.Create(); d__.<>1__state = -1; d__.<>t__builder.Start<<BoilEggsAsync>d__5>(ref d__); return d__.<>t__builder.Task;}

Page 13: Asynchronous programming Deadlock All The Things!.

Page / Copyright ©2014 by Readify Pty Ltd13

Awaiting a result› Awaiting a task will schedule a continuation block

› Everything after the awaiting task will be executed when the task is done executingpublic async Task RunAsync(){ var resultTask = Task<string>.Run(() => { Thread.Sleep(2000);

return "Hello World!"; });

var result = await resultTask;}

Back on the UI thread after the waiting is done

@fekberg

Page 14: Asynchronous programming Deadlock All The Things!.

Page / Copyright ©2014 by Readify Pty Ltd14

Example of deadlocking› Wait() for an asynchronous task on the UI thread, making it impossible for the state machine to signal that it is completed!public async Task RunAsync()…

RunAsync().Wait();

@fekberg

Page 15: Asynchronous programming Deadlock All The Things!.

Page / Copyright ©2014 by Readify Pty Ltd15

Things to consider› Don’t mark void methods as asynchronous, you will have

no way of tracking it

› Tasks swallow Exceptions!

› Don’t explicitly .Wait() this is an easy path to deadlocking

› Follow the naming convention MyMethodAsync

› Don’t lie by wrapping synchronous/blocking code in async methods

› The continuation is on the calling thread!

› Async lambdas: @fekberg

async () => { await Task.Delay(2000); }

Page 16: Asynchronous programming Deadlock All The Things!.

Page / Copyright ©2014 by Readify Pty Ltd16Page @fekberg

Page 17: Asynchronous programming Deadlock All The Things!.

Page / Copyright ©2014 by Readify Pty Ltd17

Summary› Async is powerful

› Using Async wrong may deadlock your application

› Can be hard to debug

› Await all your tasks to verify the execution!

@fekberg

Page 18: Asynchronous programming Deadlock All The Things!.

/ Copyright ©2014 by Readify Pty Ltd18Page

Questions?

Page 19: Asynchronous programming Deadlock All The Things!.

/ Copyright ©2014 by Readify Pty Ltd19Page

Thank [email protected]

http://fekberg.com

+61 (401) 157-608

@fekberg

C# Smorgasbord