View
224
Download
0
Category
Tags:
Preview:
Citation preview
Asynchronous programming
Deadlock All The Things!
/ Copyright ©2014 by Readify Pty Ltd2Page
Filip Ekbergfilip.ekberg@readify.net
http://fekberg.com
+61 (401) 157-608
@fekberg
C# Smorgasbord
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 / Copyright ©2014 by Readify Pty Ltd4
Async + Parallel12:38
Load app content
Sort data
Process
records
Asynchronous task
@fekberg
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 / 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 / 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 / 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 / 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 / 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 / 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 / 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 / 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 / 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 / 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 / Copyright ©2014 by Readify Pty Ltd16Page @fekberg
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
/ Copyright ©2014 by Readify Pty Ltd18Page
Questions?
/ Copyright ©2014 by Readify Pty Ltd19Page
Thank you!filip.ekberg@readify.net
http://fekberg.com
+61 (401) 157-608
@fekberg
C# Smorgasbord
Recommended