async await
Post on 16-Jul-2015
141 Views
Preview:
TRANSCRIPT
J e f f H a r t
V a n i s h i n g C l o u d s , I n c .
Async/Await for Fun and Profit
Multithreading is just one damn thing after…
…before, or the simultaneously with another.
Scott Meyers and Andrei Alexandrescu
…before
March 19, 2013
Why Multithreading?
“Modern” apps force multithreading
Desktop/client – avoiding the “toilet bowl”
Server-side scalability – all about the cores
Economics – computers not faster since P4 (90nm)
Copyright © Jeff Hart, 2015
Know Your Goal
Offloading – free the “main” thread
Still uses another (Thread Pool) thread
Works for CPU bound (i.e., thread backed)
Scaling – not using “any” thread
Still uses IO completion ports
Only works for IO bound provided by “framework”
Copyright © Jeff Hart, 2015
Domain: Prime Numbers
Natural numbers only divisible by itself c and 1for(int d=2; d<c-1; d++)…
Only even prime is 2for(int d=3; d<c-1; d+=2)…
If c/d = q, then c/q = d; and q or d ≤ SQRT(c)for(int d=3; d<=Math.Sqrt(c); d+=2)…
If c/d, then d is a prime or divisible by one<dSo only test against previously found primes
… lots of more powerful sieves
Copyright © Jeff Hart, 2015
First Attempt
Copyright © Jeff Hart, 2015
var nums = Enumerable.Range(1, Math.Sqrt(c));
var query =nums.AsParallel().Where(n => IsPrime(n));
var primes = query.ToArray();
Problems:
Doesn’t scale (parallel “never” does)
Doesn’t improve perf on a loaded system
May not improve perf “anyway”
Which Would You Prefer?
Copyright © Jeff Hart, 2015
(100s)
(100s)
(100s)
(100s)
(100s)
Synchronous
500s elapsed1 thread
(100s)
(100s)
(100s)
(100s)
(100s)
Parallel
300s elapsed2 threads
Asynchronous
100.1s elapsed1 thread
(100s)
(100s)
(100s)
(100s)
(100s)
20ms
Simple Code
Copyright © Jeff Hart, 2015
public async void Click(){var client = new AsyncSample();int answer = await client.LongAsync();txtResult.Text = "Life the universe..."
}
class AsyncSample{public async Task<int> LongAsync(){
var client = new FrameworkClass();Task task = client.LongAsync();…int result = await task;…
}}
CPU Bound IO Bound
Copyright © Jeff Hart, 2015
Needs “backing” thread
Parallel.ForEach and Task.Run
Unless writing scalable (server-side) code
Special advice to “library” writers (don’t lie/chatty)
Threads don’t increase throughput under load
Doesn’t need/want
Always use awaitrather than another (background) thread
Ying Yang
Misconceptions about async/await
Copyright © Jeff Hart, 2015
async modifier: method is async
await keyword: call the async method
and wait until it returns
suspends the thread
async modifier: method may call async methods/
use await
await keyword: call the async method and return
immediately (assuming it does); when method completes, continue from here
suspends the method (IP)
Basic ROT
Using await forces signature to: async Task[<T>]
Warning if async method without using await
await converts Task<T> to <T> (Task to void)
Method returns Task<T>, but you return T;
If you have used await
Async is cheap—but does allocate; the GC costs
State machine for method’s local variables
A delegate
Task object
Copyright © Jeff Hart, 2015
Rules
Copyright © Jeff Hart, 2015
Can’t await in catch/finally (C#6/VS15) or lock
Can’t make properties async
“Never” call async void (event handlers only)
Or if you must “fire and forget”
How Sweet the Syntactic Sugar Is
async Task<T> MyMethodAsync(«args»){var client = …var r = await client.WhateverAsync(…);… use r, as neededreturn «some expression <T>, i.e., r»;
}
async Task<T> MyMethodAsync(«args»){var tcs = TaskCompletionSource<T>();var client = …client.WhateverAsync(…).ContinueWith(task -> {
var r = task.Result;… use r, as neededtcs.SetResult(«some expression <T>, i.e., r»)
});return tcs.Task;
}
Copyright © Jeff Hart, 2015
Task Class – a Promise…
ctors – not typically used (takes Action<T>)
Properties
Factory, CreationOptions
IsCanceled, IsCompleted, IsFaulted and Status
Methods
Task.Delay – replaces Thread.Sleep
Task.Run – new in 4.5 (simple sugar)
FromResult<T>
ConfigureAwait(bool continueOnCapturedContext)
ContinueWith…, Wait…, WaitAll…, WaitAny…, Task.Yield
Copyright © Jeff Hart, 2015
Floor to Ceiling
Go down to:
Framework XxxAsync for scaling
“Creating” asynchronicity
Task.Run( { … } ) way better than worker threads
Go up to:
Handler
MSTest, etc.
Or “eat” the asynchronicity
task.ContinueWith( …, TaskContinuationOptions.Only|Not)
task.Result - blocks
Copyright © Jeff Hart, 2015
We’ve Been At This…
CLR v1: APM – Async Programming Model
Simple (mechanical) but limiting
CLR v2: EAP – Event-based Asynchronous Pattern
Very flexible but lots of “namespace noise”
CLR v4: TAP – Task-based Asynchronous Pattern
V4.5 async/await “complier sugar”
Copyright © Jeff Hart, 2015
Async Programming Model
IAsyncResult BeginDoIt(path,…, DoitCallback, doItState);
public void DoItCallback(IAsyncResult result){…var i = int EndDoIt(result);
}
int DoIt(string path,…); (inputs)
(added—optional)
Options:1. Block2. Wait Handle3. Poll4. Callback
Interface with• AsyncState• AsyncWaitHandle• IsCompleted• CompletedSynchronously
Copyright © Jeff Hart, 2015
Event-based Asynchronous Pattern
delegate void DoItCompletedEventHandler(object sender, DoItCompletedArgs args);
class DoItCompletedArgs :AsyncCompletedEventArgs{
int Result{ get; set; }
}
class MyClass{
void DoItAsync(string path,…);
Event DoItCompletedEventHandler DoItCompleted;
}
Copyright © Jeff Hart, 2015
Task-based Asynchronous Pattern
class MyClass{
async Task<int> DoItAsync(string path,…);
}
Copyright © Jeff Hart, 2015
Transitioning from APM
static Task<int> ToDoItAsync(this MyClass mc, string path,…)
{if( mc==null ) throw new ArgumentNullException(…
return Task<int> task = Task.Factory.FromAsync<int>(mc.BeginDoIt, mc.EndDoIt, path,…);
}
Copyright © Jeff Hart, 2015
Getting Real (Data)
Entity Framework 6 is TAP enabled
Secret: using System.Data.Entity;
All|AnyAsync
Count|Average|Sum|Min|MaxAsync
ContainsAsync
First|Single[OrDefault]Async
ForEachAsync
LoadAsync
ToArray|List|DictionaryAsync
Copyright © Jeff Hart, 2015
Graduation
foreach( var d in GetLotsOfData() ){DoSomethingReallyLong(d);
}
Parallel.ForEach( GetLotsOfData(), d=>{DoSomethingReallyLong(d);
}
var tasks = new List<Task>()foreach( var d in GetLotsOfData() ){
tasks.Add(DoSomethingReallyLongAsync(d));}Task.AwaitAll(tasks);
?
Copyright © Jeff Hart, 2015
Layers of Multithreading
Async/await two-step
Separating task and await
Knowin’ when to make ‘em;And knowin’ when to tend ‘em
Rules of Thumb
Mostly compiler enforced/assisted
Avoid async void (fire and forget)
Go “floor to ceiling” when possible
Task’s members to “stop”
TaskCompletionSource to “create”
The scary bit:Synchronizing (data)
Copyright © Jeff Hart, 2015
SpeakerRate.com h t t p : / / s p e a k e r r a t e . c o m / t a l k s / 5 3 5 0 1 - a s y n c - a w a i t - f o r - f u n -a n d - p r o f i t
S e a r c h f o r “ A s y n c / A w a i t f o r F u n a n d P r o f i t ”
Thank YOU!
Copyright © Jeff Hart, 2015
23
top related