45
Demystifying the .NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart [email protected]

Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart [email protected]

Embed Size (px)

Citation preview

Page 1: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Demystifying the .NET Asynchronous Programming LandscapeBart J.F. De Smetblogs.bartdesmet.net/[email protected]

Page 2: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

It’s All About Time!

• What’s asynchrony?• Greek origin• a (not)• syn (together with)• chronos (time)

• Multiple parties evolving in time independently• Not being blocked

• Related concepts• Concurrency• Order in which multiple tasks execute is not determined

• Parallelism• True simultaneous execution (e.g. multicore)

Page 3: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

It’s a Jungle Out There!

Your Program Here

Eventstriggered

I/O

completed

Packet

received

EventsCallbacks

Reactive

Page 4: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Nobody Likes to be Blocked

• A connected world with I/O• Network sockets• Web services• Instant messaging

• Don’t block the UI thread!• PostMessage• Control.Invoke• Dispatcher.BeginInvoke

• Asynchrony in frameworks• Silverlight• Windows Phone 7• AJAX

Language support?

Page 5: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

From the Bottom UpHardware based on

asynchrony…

Programming model?

Page 6: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Abstractions in the .NET Framework

using System;using System.IO;

class Program{ static void Main() { var buffer = new byte[4 * 1024 * 1024 /* 4MB */];

using (var fs = File.OpenRead(@“c:\temp\sample.big”)) { fs.BeginRead(buffer, 0, buffer.Length, iar => { // Process results in buffer }, null); } }}

Spot the defects

Callback using a lambda expression

Lack of closures in C# 1.0

Lifetime issues?

Need EndRead?

Page 7: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Abstractions in the .NET Framework

• Asynchronous Methods

• Event-Based Asynchronous Pattern

• BackgroundWorker Component

IAsyncResult BeginRead(…, AsyncCallback callback, object state);int EndRead(IAsyncResult result);

void DownloadAsync(…);event DownloadCompletedEventHandler DownloadCompleted;

void RunWorkerAsync();void ReportProgress(int percentProgress);

event DoWorkEventHandler DoWork;event ProgressChangedEventHandler ProgressChanged;event RunWorkerCompletedEventHandler RunWorkerCompleted;

Asynchronous is not unlike event-driven

Use of callback functions

Page 8: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

DEMOAsynchronous Methods in .NET

Page 9: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

The Task Parallel Library in .NET 4

Can you keep the cores busy?

Gordon Moore

True parallelism has become reality

Page 10: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Essential TPL Concepts – Task<T>

• Representation of a computation• Also known as a “future”

• Cheaper than threads• Continuations can be hooked up• Also known as “continuation passing style” (CPS)

Task<int> x = Task<int>.Factory.StartNew(() => { // (Long-running) computation of the result.});

x.ContinueWith(x2 => { // Code for the continuation after x completes, // with x2 an alias for the original task.});

Your application logic ends up inside out

Code runs on the CLR’s task pool

Continuations allow for sequencing

Page 11: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Continuations for Dummies

var report = Task.Factory.StartNew(() => GetFileData())

Returns abyte[]

.ContinueWith(x => Analyze(x.Result))

Receives aTask<byte[]>

.ContinueWith(y => Summarize(y.Result));

Data available in byte[]

What about errors? Returns a

double[]Receives a

Task<double[]>

Data Flow

Pipeline

Page 12: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

DEMOWorking with Task<T> in .NET 4

Page 13: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Language Support for Asynchronous Programming – F#

13

let processAsync i = async { use stream = File.OpenRead(sprintf "Image%d.tmp" i) let! pixels = stream.AsyncRead(numPixels) let pixels' = transform pixels i use out = File.OpenWrite(sprintf "Image%d.done" i) do! out.AsyncWrite(pixels') }

let processAsyncDemo = printfn "async demo..." let tasks = [ for i in 1 .. numImages -> processAsync i ] Async.RunSynchronously (Async.Parallel tasks) |> ignore printfn "Done!"

stream.Read(numPixels, pixels -> let pixels' = transform pixels i use out = File.OpenWrite(sprintf "Image%d.done" i) do! out.AsyncWrite(pixels'))

Com

pile

r

Tran

sform

ation

Page 14: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

(Asynchronous) Workflows in F#

• General-purpose language feature introduced by F#• Based on theory of monads• More exhaustive compared to LINQ in C# and VB• Overloadable meaning for specific keywords

• Continuation passing style• Synchronous: ‘a -> ‘b• Asynchronous:‘a -> (‘b -> unit) -> unit• In C# style: Action<T, Action<R>>

• Core concept: async { /* code */ }• Syntactic sugar for keywords inside block• E.g. let!, do!, use!

Continuation function receives result (~ ContinueWith)

Page 15: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

DEMOAsynchronous Workflows in F#

Page 16: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Introducing the Visual Studio Async CTP

16

PDC 2010

Page 17: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Asynchronous Control Flow

async void DoWorkAsync() { var t1 = ProcessFeedAsync("www.acme.com/rss"); var t2 = ProcessFeedAsync("www.xyznews.com/rss"); await Task.WhenAll(t1, t2); DisplayMessage("Done");}

async Task ProcessFeedAsync(string url) { var text = await DownloadFeedAsync(url); var doc = ParseFeedIntoDoc(text); await SaveDocAsync(doc); ProcessLog.WriteEntry(url);}

UI Thread

Message Pump

Page 18: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Asynchronous Control Flow

async void DoWorkAsync() { var t1 = ProcessFeedAsync("www.acme.com/rss"); var t2 = ProcessFeedAsync("www.xyznews.com/rss"); await Task.WhenAll(t1, t2); DisplayMessage("Done");}

async Task ProcessFeedAsync(string url) { var text = await DownloadFeedAsync(url); var doc = ParseFeedIntoDoc(text); await SaveDocAsync(doc); ProcessLog.WriteEntry(url);}

Page 19: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Asynchronous Control Flow

async void DoWorkAsync() { var t1 = ProcessFeedAsync("www.acme.com/rss"); var t2 = ProcessFeedAsync("www.xyznews.com/rss"); await Task.WhenAll(t1, t2); DisplayMessage("Done");}

async Task ProcessFeedAsync(string url) { var text = await DownloadFeedAsync(url); var doc = ParseFeedIntoDoc(text); await SaveDocAsync(doc); ProcessLog.WriteEntry(url);}

Page 20: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Asynchronous Control Flow

async void DoWorkAsync() { var t1 = ProcessFeedAsync("www.acme.com/rss"); var t2 = ProcessFeedAsync("www.xyznews.com/rss"); await Task.WhenAll(t1, t2); DisplayMessage("Done");}

async Task ProcessFeedAsync(string url) { var text = await DownloadFeedAsync(url); var doc = ParseFeedIntoDoc(text); await SaveDocAsync(doc); ProcessLog.WriteEntry(url);}

Page 21: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Asynchronous Control Flow

async void DoWorkAsync() { var t1 = ProcessFeedAsync("www.acme.com/rss"); var t2 = ProcessFeedAsync("www.xyznews.com/rss"); await Task.WhenAll(t1, t2); DisplayMessage("Done");}

async Task ProcessFeedAsync(string url) { var text = await DownloadFeedAsync(url); var doc = ParseFeedIntoDoc(text); await SaveDocAsync(doc); ProcessLog.WriteEntry(url);}

t1

Page 22: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Asynchronous Control Flow

async void DoWorkAsync() { var t1 = ProcessFeedAsync("www.acme.com/rss"); var t2 = ProcessFeedAsync("www.xyznews.com/rss"); await Task.WhenAll(t1, t2); DisplayMessage("Done");}

async Task ProcessFeedAsync(string url) { var text = await DownloadFeedAsync(url); var doc = ParseFeedIntoDoc(text); await SaveDocAsync(doc); ProcessLog.WriteEntry(url);}

t1

t2

Page 23: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Asynchronous Control Flow

async void DoWorkAsync() { var t1 = ProcessFeedAsync("www.acme.com/rss"); var t2 = ProcessFeedAsync("www.xyznews.com/rss"); await Task.WhenAll(t1, t2); DisplayMessage("Done");}

async Task ProcessFeedAsync(string url) { var text = await DownloadFeedAsync(url); var doc = ParseFeedIntoDoc(text); await SaveDocAsync(doc); ProcessLog.WriteEntry(url);}

t1

t2

Page 24: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Asynchronous Control Flow

async void DoWorkAsync() { var t1 = ProcessFeedAsync("www.acme.com/rss"); var t2 = ProcessFeedAsync("www.xyznews.com/rss"); await Task.WhenAll(t1, t2); DisplayMessage("Done");}

async Task ProcessFeedAsync(string url) { var text = await DownloadFeedAsync(url); var doc = ParseFeedIntoDoc(text); await SaveDocAsync(doc); ProcessLog.WriteEntry(url);}

t1

t2

Page 25: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Asynchronous Control Flow

async void DoWorkAsync() { var t1 = ProcessFeedAsync("www.acme.com/rss"); var t2 = ProcessFeedAsync("www.xyznews.com/rss"); await Task.WhenAll(t1, t2); DisplayMessage("Done");}

async Task ProcessFeedAsync(string url) { var text = await DownloadFeedAsync(url); var doc = ParseFeedIntoDoc(text); await SaveDocAsync(doc); ProcessLog.WriteEntry(url);}

t1

t2

Page 26: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Asynchronous Control Flow

async void DoWorkAsync() { var t1 = ProcessFeedAsync("www.acme.com/rss"); var t2 = ProcessFeedAsync("www.xyznews.com/rss"); await Task.WhenAll(t1, t2); DisplayMessage("Done");}

async Task ProcessFeedAsync(string url) { var text = await DownloadFeedAsync(url); var doc = ParseFeedIntoDoc(text); await SaveDocAsync(doc); ProcessLog.WriteEntry(url);}

t1

t2

Page 27: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Asynchronous Control Flow

async void DoWorkAsync() { var t1 = ProcessFeedAsync("www.acme.com/rss"); var t2 = ProcessFeedAsync("www.xyznews.com/rss"); await Task.WhenAll(t1, t2); DisplayMessage("Done");}

async Task ProcessFeedAsync(string url) { var text = await DownloadFeedAsync(url); var doc = ParseFeedIntoDoc(text); await SaveDocAsync(doc); ProcessLog.WriteEntry(url);}

t1

t2

Page 28: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Asynchronous Control Flow

async void DoWorkAsync() { var t1 = ProcessFeedAsync("www.acme.com/rss"); var t2 = ProcessFeedAsync("www.xyznews.com/rss"); await Task.WhenAll(t1, t2); DisplayMessage("Done");}

async Task ProcessFeedAsync(string url) { var text = await DownloadFeedAsync(url); var doc = ParseFeedIntoDoc(text); await SaveDocAsync(doc); ProcessLog.WriteEntry(url);}

t1

t2

Page 29: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Asynchronous Control Flow

async void DoWorkAsync() { var t1 = ProcessFeedAsync("www.acme.com/rss"); var t2 = ProcessFeedAsync("www.xyznews.com/rss"); await Task.WhenAll(t1, t2); DisplayMessage("Done");}

async Task ProcessFeedAsync(string url) { var text = await DownloadFeedAsync(url); var doc = ParseFeedIntoDoc(text); await SaveDocAsync(doc); ProcessLog.WriteEntry(url);}

t1

t2

Page 30: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Asynchronous Control Flow

async void DoWorkAsync() { var t1 = ProcessFeedAsync("www.acme.com/rss"); var t2 = ProcessFeedAsync("www.xyznews.com/rss"); await Task.WhenAll(t1, t2); DisplayMessage("Done");}

async Task ProcessFeedAsync(string url) { var text = await DownloadFeedAsync(url); var doc = ParseFeedIntoDoc(text); await SaveDocAsync(doc); ProcessLog.WriteEntry(url);}

t1

t2

Page 31: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Asynchronous Control Flow

async void DoWorkAsync() { var t1 = ProcessFeedAsync("www.acme.com/rss"); var t2 = ProcessFeedAsync("www.xyznews.com/rss"); await Task.WhenAll(t1, t2); DisplayMessage("Done");}

async Task ProcessFeedAsync(string url) { var text = await DownloadFeedAsync(url); var doc = ParseFeedIntoDoc(text); await SaveDocAsync(doc); ProcessLog.WriteEntry(url);}

t1

t2

Page 32: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Asynchronous Control Flow

async void DoWorkAsync() { var t1 = ProcessFeedAsync("www.acme.com/rss"); var t2 = ProcessFeedAsync("www.xyznews.com/rss"); await Task.WhenAll(t1, t2); DisplayMessage("Done");}

async Task ProcessFeedAsync(string url) { var text = await DownloadFeedAsync(url); var doc = ParseFeedIntoDoc(text); await SaveDocAsync(doc); ProcessLog.WriteEntry(url);}

t1

t2

Page 33: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Asynchronous Control Flow

async void DoWorkAsync() { var t1 = ProcessFeedAsync("www.acme.com/rss"); var t2 = ProcessFeedAsync("www.xyznews.com/rss"); await Task.WhenAll(t1, t2); DisplayMessage("Done");}

async Task ProcessFeedAsync(string url) { var text = await DownloadFeedAsync(url); var doc = ParseFeedIntoDoc(text); await SaveDocAsync(doc); ProcessLog.WriteEntry(url);}

t1

t2

Page 34: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

DEMOVisual Studio Async CTP

Page 35: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Events Are All Around Us

Socialmedia

Stock tickers

RSS feeds

GPS

Server managementUI e

vents

Page 36: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Event Processing Systems

Rx is a library for composing asynchronous

and event-based programs using observable

sequences.

( 𝑓 ◦𝑔)(𝑥 )= 𝑓 (𝑔(𝑥 ))

Queries! LINQ!

Way simpler with Rx

• .NET 3.5 SP1 and 4.0• Silverlight 3, 4, and 5• XNA 4.0 for Xbox 360• Windows Phone 7• JavaScript (RxJS)

Download at MSDN Data Developer Center or use NuGet

Page 37: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Environment

Mov

eNex

tGot next?

Application

OnN

ext Have next!

IEnumerable<T>IEnumerator<T>

IObservable<T>IObserver<T>

Inte

racti

ve ReactivePush-Based Data Retrieval

Page 38: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Event Programming Interfaces

interface IObservable<out T>{ IDisposable Subscribe(IObserver<T> observer);}

interface IObserver<in T>{ void OnNext(T value); void OnError(Exception ex); void OnCompleted();}

Both interfaces ship in the .NET 4 BCL

Observers used to define callbacks

In today’s word, errors are a given

Page 39: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Writing Rx Queries over Event Streams

// IObservable<string> from TextChanged eventsvar changed = Observable.FromEventPattern(txt, "TextChanged");var input = (from text in changed select ((TextBox)text.Sender).Text); .DistinctUntilChanged() .Throttle(TimeSpan.FromSeconds(1));

// Bridge with the dictionary web servicevar svc = new DictServiceSoapClient();var lookup = Observable.FromAsyncPattern<string, DictionaryWord[]> (svc.BeginLookup, svc.EndLookup);

// Retrieve results and hop from stream to streamvar res = (from term in input select lookup(term)) .Switch();

Importing .NET events as observables

Bridging the async method pattern

One stream per web service request

Page 40: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

DEMOEvent Processing with Rx

Page 41: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Asynchronous Data Processing Overview

#

Synchronous Asynchronous

Sing

le v

alue

(1)

Mul

tiple

val

ues

(*)

Func<T> Task<T>

IEnumerable<T> IObservable<T>

y = f(x); y = await g(x);

Invocation expressions Await expressions

Sequencing through statements

res = from x in xs from y in q(x) …;

Composition on query expressions

foreach (var z in res) …

res.Subscribe(x => …

Imperative style code

Functional style code

Page 42: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Summary

• Asynchrony is everywhere• Emergence of async-only APIs• Windows Phone, Silverlight, JavaScript

• Don’t block the UI• Have to deal with latency

• Call to action• Learn about Task<T>• Download the Async CTP• http://msdn.com/vstudio/async

• Download Reactive Extensions (Rx)• http://msdn.com/data/gg577609

Page 43: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

Stay up to date with MSDN Belux

• Register for our newsletters and stay up to date:http://www.msdn-newsletters.be• Technical updates• Event announcements and registration• Top downloads

• Follow our bloghttp://blogs.msdn.com/belux

• Join us on Facebookhttp://www.facebook.com/msdnbehttp://www.facebook.com/msdnbelux

• LinkedIn: http://linkd.in/msdnbelux/ • Twitter: @msdnbelux

Download MSDN/TechNet Desktop Gadget

http://bit.ly/msdntngadget

Page 44: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

TechDays 2011 On-Demand

• Watch this session on-demand via Channel9http://channel9.msdn.com/belux

• Download to your favorite MP3 or video player• Get access to slides and recommended resources by the speakers

Page 45: Demystifying the.NET Asynchronous Programming Landscape Bart J.F. De Smet blogs.bartdesmet.net/bart bartde@microsoft.com

THANK YOU