SlideShare a Scribd company logo
1 of 79
Download to read offline
The Evolution of Async
Programming on .NET Platform
          ZhaoJie @ SNDA
             Nov, 2010
About Me
•       /        / Jeffrey Zhao /

•
• Blog: http://blog.zhaojie.me/
• Twitter: @jeffz_cn
• F#, Scala, JavaScript, Python, .NET, mono...
• Java (as the language) hater
Agenda
• Why & How
• .NET 1.0
• .NET 2.0 / C# 2.0
• .NET 3.0 / F#
• .NET 4.0 / Reactive Framework
• Future / C# vNext
Why?


   Because the essence of
      Cloud, Web, Mobile
is asynchronous computations
How?


 By providing powerful language
features / programming model /
             libraries
.NET 1.0
Two Raw Async Models

• Begin/End
• Event-based
• Both are callback-based
 •   Which is just “asynchronous” means
Begin/End Async Model
delegate AsyncCallback(IAsyncResult);

interface IAsyncResult {
    object AsyncState { get; }
    WaitHandle AsyncWaitHandle { get; }
    bool CompletedSynchronously { get; }
    bool IsCompleted { get; }
}

void BeginXxx(arg1, arg2, ..., AsyncCallback, state);

TResult EndXxx(IAsyncResult);
Let’s write a “Transfer”
 method in 4 different
          ways
Sync
public static void Transfer(string url, Stream streamOut) {
    var request = WebRequest.Create(url);
    using (var response = request.GetResponse()) {
        var streamIn = response.GetResponseStream();

        var size = 1024;
        var buffer = new byte[size];
        while (true) {
            var lengthRead = streamIn.Read(buffer, 0, size);
            if (lengthRead <= 0) break;
            streamOut.Write(buffer, 0, lengthRead);
        }
    }
}
Async
IAsyncResult BeginTransfer(url, streamOut, ..., callback) {
    // keep context and BeginGetResponse
}

void EndGetResponse(...) {
    // get streamIn and BeginRead
}

void EndRead(...) {
    // data read, completed or BeginWrite
}

void EndWrite(...) {
    // data wrote, BeginRead
}
Async
1   IAsyncResult BeginTransfer(url, streamOut, ..., callback) {
        // keep context and BeginGetResponse
    }

    void EndGetResponse(...) {
        // get streamIn and BeginRead
    }

    void EndRead(...) {
        // data read, completed or BeginWrite
    }

    void EndWrite(...) {
        // data wrote, BeginRead
    }
Async
1   IAsyncResult BeginTransfer(url, streamOut, ..., callback) {
        // keep context and BeginGetResponse
    }
                   2
    void EndGetResponse(...) {
        // get streamIn and BeginRead
    }

    void EndRead(...) {
        // data read, completed or BeginWrite
    }

    void EndWrite(...) {
        // data wrote, BeginRead
    }
Async
1   IAsyncResult BeginTransfer(url, streamOut, ..., callback) {
        // keep context and BeginGetResponse
    }
                   2
    void EndGetResponse(...) {
        // get streamIn and BeginRead
    }
                   3
    void EndRead(...) {
        // data read, completed or BeginWrite
    }

    void EndWrite(...) {
        // data wrote, BeginRead
    }
Async
1   IAsyncResult BeginTransfer(url, streamOut, ..., callback) {
        // keep context and BeginGetResponse
    }
                   2
    void EndGetResponse(...) {
        // get streamIn and BeginRead
    }
                   3
    void EndRead(...) {
        // data read, completed or BeginWrite
    }
                   4

    void EndWrite(...) {
        // data wrote, BeginRead
    }
Async
1   IAsyncResult BeginTransfer(url, streamOut, ..., callback) {
        // keep context and BeginGetResponse
    }
                   2
    void EndGetResponse(...) {
        // get streamIn and BeginRead
    }
                   3
    void EndRead(...) {
        // data read, completed or BeginWrite
    }
5                  4

    void EndWrite(...) {
        // data wrote, BeginRead
    }
Async
1   IAsyncResult BeginTransfer(url, streamOut, ..., callback) {
        // keep context and BeginGetResponse
    }
                   2
    void EndGetResponse(...) {
        // get streamIn and BeginRead
    }
                   3
    void EndRead(...) {
        // data read, completed or BeginWrite      6
    }
5                  4

    void EndWrite(...) {
        // data wrote, BeginRead
    }
Robust & Sync
public void Transfer(string url, Stream streamOut) {
    try {
        var request = WebRequest.Create(url);
        using (var response = request.GetResponse()) {
            var streamIn = response.GetResponseStream();

            var size = 1024;
            var buffer = new byte[size];
            while (true) {
                var lengthRead = streamIn.Read(buffer, 0, size);
                if (lengthRead <= 0) break;
                streamIn.Write(buffer, 0, lengthRead);
            }
        }
    } catch {
        // ...
    }
}
Robust & Async
IAsyncResult BeginTransfer(url, streamOut, ..., callback) {
    try { ... } catch { ... }
}

void EndGetResponse(...) {
    try { ... } catch { ... }
}

void EndRead(...) {
    try { ... } catch { ... }
}

void EndWrite(...) {
    try { ... } catch { ... }
}
Event-based Async Model
class XxxCompletedEventArgs : EventArgs {
    Exception Error { get; }
    TResult Result { get; }
}

class Worker {
    event EventHandler<XxxCompletedArgs> XxxCompleted;
    void XxxAsync(arg1, arg2, ...);
}
The Evolution of Async-Programming on .NET Platform (TUP, Full)
Code Locality is Broken

• Used to expressing algorithms linearly
• Async requires logical division of algorithms
  •   No if / using / while / for ...

• Very difficult to
  •   Combine multiple asynchronous operations
  •   Deal with exceptions and cancellation
.NET 2.0 / C# 2.0
“yield” for Iterators
  IEnumerable<int> Numbers() {

      yield return 0;
  	
      yield return 1;
  	
      yield return 2;

  }
“yield” for Iterators
             IEnumerable<int> Numbers() {
MoveNext()
                 yield return 0;
             	
                 yield return 1;
             	
                 yield return 2;

             }
“yield” for Iterators
             IEnumerable<int> Numbers() {
MoveNext()
                 yield return 0;
             	
MoveNext()
                 yield return 1;
             	
                 yield return 2;

             }
“yield” for Iterators
             IEnumerable<int> Numbers() {
MoveNext()
                 yield return 0;
             	
MoveNext()
                 yield return 1;
             	
MoveNext()
                 yield return 2;

             }
“yield” for Iterators
             IEnumerable<int> Numbers() {
MoveNext()
                 yield return 0;
             	
MoveNext()
                 yield return 1;
             	
MoveNext()
                 yield return 2;
MoveNext()
             }
Async with “yield”
IEnumerator<int> Transfer(AsyncEnumerator ae, string url, Stream streamOut) {
    var request = WebRequest.Create(url);
    request.BeginGetResponse(ae.End(), null);
    yield return 1;

    using (var response = request.EndGetResponse(ae.DequeueAsyncResult())) {
        var streamIn = response.GetResponseStream();
        byte[] buffer = new byte[1024];
        while (true) {
            streamIn.BeginRead(buffer, 0, buffer.Length, ae.End(), null);
            yield return 1;

            int lengthRead = streamIn.EndRead(ae.DequeueAsyncResult());
            if (lengthRead <= 0) break;
            streamOut.BeginWrite(buffer, 0, lengthRead, ae.End(), null);
            yield return 1;

            streamOut.EndWrite(ae.DequeueAsyncResult());
        }
    }
}
Async with “yield”
    IEnumerator<int> Transfer(AsyncEnumerator ae, string url, Stream streamOut) {
        var request = WebRequest.Create(url);
        request.BeginGetResponse(ae.End(), null);
        yield return 1;

            using (var response = request.EndGetResponse(ae.DequeueAsyncResult())) {
                var streamIn = response.GetResponseStream();
                byte[] buffer = new byte[1024];
                while (true) {
                    streamIn.BeginRead(buffer, 0, buffer.Length, ae.End(), null);
“yield” after       yield return 1;
firing async
operations
                  int lengthRead = streamIn.EndRead(ae.DequeueAsyncResult());
                  if (lengthRead <= 0) break;
                  streamOut.BeginWrite(buffer, 0, lengthRead, ae.End(), null);
                  yield return 1;

                  streamOut.EndWrite(ae.DequeueAsyncResult());
              }
         }
    }
Async with “yield”
    IEnumerator<int> Transfer(AsyncEnumerator ae, string url, Stream streamOut) {
        var request = WebRequest.Create(url);
        request.BeginGetResponse(ae.End(), null);
        yield return 1;

            using (var response = request.EndGetResponse(ae.DequeueAsyncResult())) {
                var streamIn = response.GetResponseStream();
                byte[] buffer = new byte[1024];
                while (true) {
                    streamIn.BeginRead(buffer, 0, buffer.Length, ae.End(), null);
“yield” after       yield return 1;
firing async
operations
                  int lengthRead = streamIn.EndRead(ae.DequeueAsyncResult());
                  if (lengthRead <= 0) break;
                  streamOut.BeginWrite(buffer, 0, lengthRead, ae.End(), null);
                  yield return 1;

                  streamOut.EndWrite(ae.DequeueAsyncResult());           continue when
              }                                                         async operations
         }                                                                 completed
    }
“yield return” for Async

• Coming with new programming patterns
• Keep code locality
  •   Good parts: support if / using / while / for ...
  •   But not perfect: cannot use try...catch

• The primitives for Fibers - lightweight
  computation units
.NET 3.0 / F#
F#
• Language by Don Syme, MS Research
• Strongly statically typed language
• Functional language with OO ability
• For industry and education
 •   Open source (Apache 2.0)
 •   Cross-platform supported by Microsoft
Concurrency Challenges

• Shared State - Immutability
• Code Locality - async { ... }
• I/O Parallelism - async { ... }
• Scaling to Multi-Machine - Agents with
  async { ... }
What’s async { ... }
... the principle we go by is, don't expect to see
a particular concurrency model put into C#
because there're many different concurrency
model ... it's more about finding things are
common to to all kinds of concurrency ...

                              - Anders Hejlsberg
Async Workflow
async { 	
    let! res = <async work>
    ...	
}
Async Workflow
            React!
async { 	
    let! res = <async work>
    ...	
}
Async Workflow
              React!
async { 	
    let! res = <async work>
    ...	
}
        an HTTP Response
            an UI Event
         a Timer Callback
        a Query Response
     a Web Servcie Response
      a Disk I/O Completion
         an Agent Message
Async in F#
let transferAsync (url: string) (streamOut: Stream) = async {

    let request = WebRequest.Create(url)
    use! response = request.AsyncGetResponse()
    let streamIn = response.GetResponseStream()

    let rec transferDataAsync (buffer: byte[]) = async {
        let! lengthRead = streamIn.AsyncRead(buffer, 0, buffer.Length)
        if lengthRead > 0 then
            do! streamOut.AsyncWrite(buffer, 0, lengthRead)
            do! transferDataAsync buffer
    }

    do! transferDataAsync (Array.zeroCreate 1024)
}
Async in F#
let transferAsync (url: string) (streamOut: Stream) = async {

    let request = WebRequest.Create(url)
    use! response = request.AsyncGetResponse()
                            AsyncGetResponse
    let streamIn = response.GetResponseStream()

    let rec transferDataAsync (buffer: byte[]) = async {
        let! lengthRead = streamIn.AsyncRead(buffer, 0, buffer.Length)
                                   AsyncRead
        if lengthRead > 0 then
            do! streamOut.AsyncWrite(buffer, 0, lengthRead)
                          AsyncWrite
            do! transferDataAsync buffer
    }
                                                      simply generate from
    do! transferDataAsync (Array.zeroCreate 1024)      Begin/End methods
}
How async { ... } Works
   async {
       let! img = AsyncRead "http://..."
       printfn "loaded!"
       do! AsyncWrite img @"c:..."
       printfn "saved!" }
How async { ... } Works
       async {
           let! img = AsyncRead "http://..."
           printfn "loaded!"
           do! AsyncWrite img @"c:..."
           printfn "saved!" }


                        =
async.Delay(fun ->
	 async.Bind(AsyncRead "http://...", (fun img ->
	 	 printfn "loaded!"
	 	 async.Bind(AsyncWrite img @"c:...", (fun () ->
	 	 	 printfn "saved!"
	 	 	 async.Return())))))
F# Async Workflow
• Library, not a language feature
  •   Based on Computation Expressions in F#

• Support all kinds of language constructions
  •   Error handling: try...catch
  •   Loop: while / for (like “foreach” in C#)
  •   Others: if / use (like “using” in C#), etc.

• Easy to
  •   Combine multiple asynchronous operations
  •   Deal with exceptions and cancellation
F# Resources
                 http://fsharp.net




Programming F#     Expert F# 2.0     Real World FP
.NET 4.0 / Reactive
   Framework
Reactive Framework

 Fundamentally change the way you
   think about coordinating and
  orchestrating asynchronous and
     event-based programming
How


By showing that asynchronous and
 event-base computations are just
      push-based collections
Interactive                 Reactive
              Environment



               Program
Enumerable Collections
 interface IEnumerable<out T> {
     IEnumerator<T> GetEnumerator();
 }

 interface IEnumerator<out T> {
     bool MoveNext();
     T Current { get; }
 }
Dualize
Observable Collections
interface IObservable<out T> {
    IDisposable Subscribe(IObserver<T> o)
}

interface IObserver<in T> {
    void OnCompleted();
    void OnNext(T item);
    void OnError(Exception ex);
}
IEnumerable & IEnumerator are prototypical
interfaces for interactive collections and
interactive programs.

IObservable & IObserver are prototypical
interfaces for observable collections and
reactive, asynchronous & event-based programs.
LINQ to Observable

        If you are writing
    LINQ or declarative code
   in an interactive program...
LINQ to Observable

         If you are writing
     LINQ or declarative code
    in an interactive program...


  You already know how to use it!
Again
... the principle we go by is, don't expect to see
a particular concurrency model put into C#
because there're many different concurrency
model ... it's more about finding things are
common to to all kinds of concurrency ...

                              - Anders Hejlsberg
Again
... the principle we go by is, don't expect to see
a particular concurrency model put into C#
because there're many different concurrency
model ... it's more about finding things are
common to to all kinds of concurrency ...

                              - Anders Hejlsberg
Move by WASD
// filter the KeyPress events when playing
var keyPress = GetKeyPress().Where(_ => isPlaying);

// filter the events to move left
var moveLeft = from ev in keyPress
               where ev.EventArgs.KeyChar == 'a'
               where ball.Left > 0
               select ev;
moveLeft.Subscribe(_ => ball.Left -= 5);

// filter the events to move top
var moveTop = from ev in keyPress
              where ev.EventArgs.KeyChar == 'w'
              where ball.Top > 0
              select ev;
moveTop.Subscribe(_ => ball.Top -= 5);
Mouse Drag and Draw
var mouseMove = GetMouseMove();
var mouseDiff = mouseMove.Zip(mouseMove.Skip(1),
    (prev, curr) => new
    {
        PrevPos = new Point(
            prev.EventArgs.X, prev.EventArgs.Y),
        CurrPos = new Point(
            curr.EventArgs.X, curr.EventArgs.Y)
    });

var mouseDrag = from _ in GetMouseDown()
                from diff in mouseDiff.TakeUntil(GetMouseUp())
                select diff;

mouseDrag.Subscribe(d => DrawLine(d.PrevPos, d.CurrPos));
Everything in Web is
    Asynchronous
• User actions
• AJAX requests
• Animations
• ...
Rx in JavaScript
• A full featured port for JavaScript
  •   Easy-to-use conversions from existing DOM,
      XmlHttpRequest, etc
  •   In a download size of less than 7kb (gzipped)

• Bindings for various libraries / frameworks
  •   jQuery
  •   MooTools
  •   Dojo
  •   ...
Drag and Draw in JS
var target = $("#paintPad");
var mouseMove = target.toObservable("mousemove");
var mouseDiff = mouseMove.Zip(mouseMove.Skip(1),
    function(prev, curr) {
        return {
            prevPos: { x: prev.clientX, y: prev.clientY },
            currPos: { x: curr.clientX, y: curr.clientY }
        };
    });

var mouseDown = target.toObservable("mousedown");
var mouseUp = target.toObservable("mouseup");
var mouseDrag = mouseDown.SelectMany(function() {
    mouseDiff.TakeUntil(mouseUp);
});

mouseDrag.Subscribe(
    function(d) { drawLine(d.prevPos, d.currPos); });
Wikipedia Lookup
var textBox = $("#searchInput");
var searcher = textBox
    .toObservable("keyup")
    .Throttle(500)
    .Select(function(_) { return textBox.val(); })
    .Select(function(term) { return queryWikipedia(term); })
    .Switch();

searcher.Subscribe(
    function(data) {
        var results = $("#results");
        results.empty();
        $.each(data, function(_, value) {
            results.append($("<li/>").text(value));
        });
    },
    function(error) { $("#error").html(error); });
Time Flies like an Arrow
var container = $("#container");
var mouseMove = container.toObservable("mousemove");

for (var i = 0; i < text.length; i++) {
    (function(i) {
        var ele = $("<span/>").text(text.charAt(i));
        ele.css({position: "absolute"}).appendTo(container);

        mouseMove.Delay(i * 100).Subscribe(function (ev) {
            ele.css({
                left: ev.clientX + i * 20 + 15 + "px",
                top: ev.clientY + "px"
            });
        });

    })(i);
Benefits of Rx
• Easy to composite and coordinate async
  operations

• Express the algorithm in functional ways
  •   Helper method: For / While / If / Try / Switch...

• Easy to be unit tested
• ...
Rx & Language Features
• Features in C# that Rx uses
 •   Extension method
 •   Lambda expression & closure
 •   Type inference
 •   LINQ query expression

• Rx has been implemented in ...
 •   C# & VB
 •   JavaScript
 •   F#
Portability
• Rx can be easily ported to various languages
  •   Scala
  •   Ruby
  •   Python
  •   modern languages with basic functional features

• Almost impossible to implement Rx in Java
  •   Cannot extend a type without breaking code
  •   Missing enough functional features
Rx Resources
• Matthew Podwysocki
 •   http://codebetter.com/blogs/matthew.podwysocki/

• Reactive Framework on MSDN DevLabs
 •   http://msdn.microsoft.com/en-us/devlabs/
     ee794896.aspx

• Tomáš Petříček
 •   http://tomasp.net/
Comparison

• F# Async Workflow
 •   Elegant, simple, easy to use
 •   Can only be used at server-side (WebSharper come to
     rescure?)

• Reactive Framework
 •   Can be used at both server-side and client-side.
 •   New async model brings learning cost.
Out of Topic


Can we programming like F# in JavaScript?
Jscex & Jscex.Async


• Computation Expressions and Async
  Workflow implemented in JavaScript

• http://github.com/jeffreyzhao/jscex
Clock

var drawClockAsync = eval(Jscex.compile("$async",
    function(interval) {
        while (true) {
            drawClock(new Date());
            $await(Jscex.Async.sleep(interval));
        }
    }
));

Jscex.Async.start(drawClockAsync(1000));
Animation
var moveAsync = eval(Jscex.compile("$async",
    function(e, start, end, duration) {
        for (var t = 0; t < duration; t += 50) {
            e.style.left = start.x + (end.x - start.x) * t / duration;
            e.style.top = start.y + (end.y - start.y) * t / duration;
            $await(Jscex.Async.sleep(50));
        }

          e.style.left = end.x;
          e.style.top = end.y;
      }
));

var moveSquareAsync = eval(Jscex.compile("$async", function(e) {
     $await(moveAsync(e, {x:100, y:100}, {x:400, y:100}, 1000));
     $await(moveAsync(e, {x:400, y:100}, {x:400, y:400}, 1000));
     $await(moveAsync(e, {x:400, y:400}, {x:100, y:400}, 1000));
     $await(moveAsync(e, {x:100, y:400}, {x:100, y:100}, 1000));
}));
C# vNext
Source

async Task<XElement> GetRssAsync(string url) {
    var client = new WebClient();
    var task = client.DownloadStringTaskAsync(url);
    var text = await task;
    var xml = XElement.Parse(text);
    return xml;
}
Compiled
Task<XElement> GetRssAsync(string url) {
    var $builder = AsyncMethodBuilder<XElement>.Create();
    var $state = 0;
    TaskAwaiter<string> $a1;
    Action $resume = delegate {
        try {
            if ($state == 1) goto L1;
            var client = new WebClient();
            var task = client.DownloadStringTaskAsync(url);
            $state = 1;
            $a1 = task.GetAwaiter();
            if ($a1.BeginAwait($resume)) return;
        L1: var text = $a1.EndAwait();
            var xml = XElement.Parse(text);
            $builder.SetResult(xml);
        }
        catch (Exception $ex) { $builder.SetException($ex); }
    };
    $resume();
    return $builder.Task;
}
Conclusion


• Async Programming is difficult
• New programming language / feature /
  library / model can help
Q &A
Thanks

More Related Content

What's hot

12 Monkeys Inside JS Engine
12 Monkeys Inside JS Engine12 Monkeys Inside JS Engine
12 Monkeys Inside JS EngineChengHui Weng
 
Metaprogramming and Reflection in Common Lisp
Metaprogramming and Reflection in Common LispMetaprogramming and Reflection in Common Lisp
Metaprogramming and Reflection in Common LispDamien Cassou
 
About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014
About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014
About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014Fantix King 王川
 
Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.Platonov Sergey
 
Javascript engine performance
Javascript engine performanceJavascript engine performance
Javascript engine performanceDuoyi Wu
 
A deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio moduleA deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio moduleSaúl Ibarra Corretgé
 
Promise: async programming hero
Promise: async programming heroPromise: async programming hero
Promise: async programming heroThe Software House
 
Apache PIG - User Defined Functions
Apache PIG - User Defined FunctionsApache PIG - User Defined Functions
Apache PIG - User Defined FunctionsChristoph Bauer
 
Python Coroutines, Present and Future
Python Coroutines, Present and FuturePython Coroutines, Present and Future
Python Coroutines, Present and Futureemptysquare
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSAdam L Barrett
 
Python meetup: coroutines, event loops, and non-blocking I/O
Python meetup: coroutines, event loops, and non-blocking I/OPython meetup: coroutines, event loops, and non-blocking I/O
Python meetup: coroutines, event loops, and non-blocking I/OBuzzcapture
 
The Ring programming language version 1.3 book - Part 84 of 88
The Ring programming language version 1.3 book - Part 84 of 88The Ring programming language version 1.3 book - Part 84 of 88
The Ring programming language version 1.3 book - Part 84 of 88Mahmoud Samir Fayed
 
Python Yield
Python YieldPython Yield
Python Yieldyangjuven
 
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵Wanbok Choi
 
[JavaOne 2011] Models for Concurrent Programming
[JavaOne 2011] Models for Concurrent Programming[JavaOne 2011] Models for Concurrent Programming
[JavaOne 2011] Models for Concurrent ProgrammingTobias Lindaaker
 
Easy Going Groovy 2nd season on DevLOVE
Easy Going Groovy 2nd season on DevLOVEEasy Going Groovy 2nd season on DevLOVE
Easy Going Groovy 2nd season on DevLOVEUehara Junji
 

What's hot (20)

12 Monkeys Inside JS Engine
12 Monkeys Inside JS Engine12 Monkeys Inside JS Engine
12 Monkeys Inside JS Engine
 
Metaprogramming and Reflection in Common Lisp
Metaprogramming and Reflection in Common LispMetaprogramming and Reflection in Common Lisp
Metaprogramming and Reflection in Common Lisp
 
About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014
About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014
About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014
 
Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.
 
Javascript engine performance
Javascript engine performanceJavascript engine performance
Javascript engine performance
 
A deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio moduleA deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio module
 
Promise: async programming hero
Promise: async programming heroPromise: async programming hero
Promise: async programming hero
 
C++ tutorial
C++ tutorialC++ tutorial
C++ tutorial
 
asyncio internals
asyncio internalsasyncio internals
asyncio internals
 
Apache PIG - User Defined Functions
Apache PIG - User Defined FunctionsApache PIG - User Defined Functions
Apache PIG - User Defined Functions
 
Python Coroutines, Present and Future
Python Coroutines, Present and FuturePython Coroutines, Present and Future
Python Coroutines, Present and Future
 
Intro to Pig UDF
Intro to Pig UDFIntro to Pig UDF
Intro to Pig UDF
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJS
 
Python meetup: coroutines, event loops, and non-blocking I/O
Python meetup: coroutines, event loops, and non-blocking I/OPython meetup: coroutines, event loops, and non-blocking I/O
Python meetup: coroutines, event loops, and non-blocking I/O
 
Python Async IO Horizon
Python Async IO HorizonPython Async IO Horizon
Python Async IO Horizon
 
The Ring programming language version 1.3 book - Part 84 of 88
The Ring programming language version 1.3 book - Part 84 of 88The Ring programming language version 1.3 book - Part 84 of 88
The Ring programming language version 1.3 book - Part 84 of 88
 
Python Yield
Python YieldPython Yield
Python Yield
 
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
 
[JavaOne 2011] Models for Concurrent Programming
[JavaOne 2011] Models for Concurrent Programming[JavaOne 2011] Models for Concurrent Programming
[JavaOne 2011] Models for Concurrent Programming
 
Easy Going Groovy 2nd season on DevLOVE
Easy Going Groovy 2nd season on DevLOVEEasy Going Groovy 2nd season on DevLOVE
Easy Going Groovy 2nd season on DevLOVE
 

Viewers also liked

Fun With Reactive Extensions
Fun With Reactive ExtensionsFun With Reactive Extensions
Fun With Reactive ExtensionsPeter Bons
 
Introduction to Reactive Extensions
Introduction to Reactive ExtensionsIntroduction to Reactive Extensions
Introduction to Reactive ExtensionsPeter Goodman
 
Real-world applications of the Reactive Extensions
Real-world applications of the Reactive ExtensionsReal-world applications of the Reactive Extensions
Real-world applications of the Reactive ExtensionsJonas Chapuis
 
Reactive Programming in .Net - actorbased computing with Akka.Net
Reactive Programming in .Net - actorbased computing with Akka.NetReactive Programming in .Net - actorbased computing with Akka.Net
Reactive Programming in .Net - actorbased computing with Akka.NetSören Stelzer
 
Why Java Sucks and C# Rocks (Final)
Why Java Sucks and C# Rocks (Final)Why Java Sucks and C# Rocks (Final)
Why Java Sucks and C# Rocks (Final)jeffz
 
Intro to Reactive Programming
Intro to Reactive ProgrammingIntro to Reactive Programming
Intro to Reactive ProgrammingStéphane Maldini
 
Reactive programming
Reactive programmingReactive programming
Reactive programmingJianbin LIN
 

Viewers also liked (7)

Fun With Reactive Extensions
Fun With Reactive ExtensionsFun With Reactive Extensions
Fun With Reactive Extensions
 
Introduction to Reactive Extensions
Introduction to Reactive ExtensionsIntroduction to Reactive Extensions
Introduction to Reactive Extensions
 
Real-world applications of the Reactive Extensions
Real-world applications of the Reactive ExtensionsReal-world applications of the Reactive Extensions
Real-world applications of the Reactive Extensions
 
Reactive Programming in .Net - actorbased computing with Akka.Net
Reactive Programming in .Net - actorbased computing with Akka.NetReactive Programming in .Net - actorbased computing with Akka.Net
Reactive Programming in .Net - actorbased computing with Akka.Net
 
Why Java Sucks and C# Rocks (Final)
Why Java Sucks and C# Rocks (Final)Why Java Sucks and C# Rocks (Final)
Why Java Sucks and C# Rocks (Final)
 
Intro to Reactive Programming
Intro to Reactive ProgrammingIntro to Reactive Programming
Intro to Reactive Programming
 
Reactive programming
Reactive programmingReactive programming
Reactive programming
 

Similar to The Evolution of Async-Programming on .NET Platform (TUP, Full)

Async Development con Visual Studio 2012
Async Development con Visual Studio 2012Async Development con Visual Studio 2012
Async Development con Visual Studio 2012Raffaele Fanizzi
 
Asynchronous Programming in ASP.NET
Asynchronous Programming in ASP.NETAsynchronous Programming in ASP.NET
Asynchronous Programming in ASP.NETChris Dufour
 
To Infinity & Beyond: Protocols & sequences in Node - Part 2
To Infinity & Beyond: Protocols & sequences in Node - Part 2To Infinity & Beyond: Protocols & sequences in Node - Part 2
To Infinity & Beyond: Protocols & sequences in Node - Part 2Bahul Neel Upadhyaya
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on AndroidTomáš Kypta
 
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJavaNon Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJavaFrank Lyaruu
 
swift-nio のアーキテクチャーと RxHttpClient
swift-nio のアーキテクチャーと RxHttpClientswift-nio のアーキテクチャーと RxHttpClient
swift-nio のアーキテクチャーと RxHttpClientShinya Mochida
 
Asynchronous, Event-driven Network Application Development with Netty
Asynchronous, Event-driven Network Application Development with NettyAsynchronous, Event-driven Network Application Development with Netty
Asynchronous, Event-driven Network Application Development with NettyErsin Er
 
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jsAvoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jscacois
 
Visug async
Visug asyncVisug async
Visug asyncQframe
 
ikh331-06-distributed-programming
ikh331-06-distributed-programmingikh331-06-distributed-programming
ikh331-06-distributed-programmingAnung Ariwibowo
 
Why async matters
Why async mattersWhy async matters
Why async matterstimbc
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScriptQiangning Hong
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the wayOleg Podsechin
 
Flink Batch Processing and Iterations
Flink Batch Processing and IterationsFlink Batch Processing and Iterations
Flink Batch Processing and IterationsSameer Wadkar
 

Similar to The Evolution of Async-Programming on .NET Platform (TUP, Full) (20)

Async Development con Visual Studio 2012
Async Development con Visual Studio 2012Async Development con Visual Studio 2012
Async Development con Visual Studio 2012
 
Asynchronous Programming in ASP.NET
Asynchronous Programming in ASP.NETAsynchronous Programming in ASP.NET
Asynchronous Programming in ASP.NET
 
To Infinity & Beyond: Protocols & sequences in Node - Part 2
To Infinity & Beyond: Protocols & sequences in Node - Part 2To Infinity & Beyond: Protocols & sequences in Node - Part 2
To Infinity & Beyond: Protocols & sequences in Node - Part 2
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
Winform
WinformWinform
Winform
 
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJavaNon Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
 
swift-nio のアーキテクチャーと RxHttpClient
swift-nio のアーキテクチャーと RxHttpClientswift-nio のアーキテクチャーと RxHttpClient
swift-nio のアーキテクチャーと RxHttpClient
 
Asynchronous, Event-driven Network Application Development with Netty
Asynchronous, Event-driven Network Application Development with NettyAsynchronous, Event-driven Network Application Development with Netty
Asynchronous, Event-driven Network Application Development with Netty
 
Multithreading in Java
Multithreading in JavaMultithreading in Java
Multithreading in Java
 
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jsAvoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.js
 
Visug async
Visug asyncVisug async
Visug async
 
ikh331-06-distributed-programming
ikh331-06-distributed-programmingikh331-06-distributed-programming
ikh331-06-distributed-programming
 
Server Side Swift: Vapor
Server Side Swift: VaporServer Side Swift: Vapor
Server Side Swift: Vapor
 
Apache Beam de A à Z
 Apache Beam de A à Z Apache Beam de A à Z
Apache Beam de A à Z
 
JS everywhere 2011
JS everywhere 2011JS everywhere 2011
JS everywhere 2011
 
Why async matters
Why async mattersWhy async matters
Why async matters
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the way
 
From Node to Go
From Node to GoFrom Node to Go
From Node to Go
 
Flink Batch Processing and Iterations
Flink Batch Processing and IterationsFlink Batch Processing and Iterations
Flink Batch Processing and Iterations
 

More from jeffz

Wind.js无障碍调试与排错
Wind.js无障碍调试与排错Wind.js无障碍调试与排错
Wind.js无障碍调试与排错jeffz
 
JavaScript现代化排错实践
JavaScript现代化排错实践JavaScript现代化排错实践
JavaScript现代化排错实践jeffz
 
Jscex:案例、阻碍、体会、展望
Jscex:案例、阻碍、体会、展望Jscex:案例、阻碍、体会、展望
Jscex:案例、阻碍、体会、展望jeffz
 
Jscex:案例、经验、阻碍、展望
Jscex:案例、经验、阻碍、展望Jscex:案例、经验、阻碍、展望
Jscex:案例、经验、阻碍、展望jeffz
 
The Evolution of Async Programming (GZ TechParty C#)
The Evolution of Async Programming (GZ TechParty C#)The Evolution of Async Programming (GZ TechParty C#)
The Evolution of Async Programming (GZ TechParty C#)jeffz
 
Mono for .NET Developers
Mono for .NET DevelopersMono for .NET Developers
Mono for .NET Developersjeffz
 
单点登录解决方案的架构与实现
单点登录解决方案的架构与实现单点登录解决方案的架构与实现
单点登录解决方案的架构与实现jeffz
 
Documentation Insight技术架构与开发历程
Documentation Insight技术架构与开发历程Documentation Insight技术架构与开发历程
Documentation Insight技术架构与开发历程jeffz
 
Windows Phone应用开发心得
Windows Phone应用开发心得Windows Phone应用开发心得
Windows Phone应用开发心得jeffz
 
分布式版本管理
分布式版本管理分布式版本管理
分布式版本管理jeffz
 
使用.NET构建轻量级分布式框架
使用.NET构建轻量级分布式框架使用.NET构建轻量级分布式框架
使用.NET构建轻量级分布式框架jeffz
 
针对iPad平台的高性能网站架构
针对iPad平台的高性能网站架构针对iPad平台的高性能网站架构
针对iPad平台的高性能网站架构jeffz
 
企业开发领域的语言特性
企业开发领域的语言特性企业开发领域的语言特性
企业开发领域的语言特性jeffz
 
大话程序员可用的算法
大话程序员可用的算法大话程序员可用的算法
大话程序员可用的算法jeffz
 
面向对象与生活
面向对象与生活面向对象与生活
面向对象与生活jeffz
 
Windows内核技术介绍
Windows内核技术介绍Windows内核技术介绍
Windows内核技术介绍jeffz
 
F#语言对异步程序设计的支持
F#语言对异步程序设计的支持F#语言对异步程序设计的支持
F#语言对异步程序设计的支持jeffz
 
大众点评网的技术变迁之路
大众点评网的技术变迁之路大众点评网的技术变迁之路
大众点评网的技术变迁之路jeffz
 
Better Framework Better Life
Better Framework Better LifeBetter Framework Better Life
Better Framework Better Lifejeffz
 
如何成为一名优秀的博主
如何成为一名优秀的博主如何成为一名优秀的博主
如何成为一名优秀的博主jeffz
 

More from jeffz (20)

Wind.js无障碍调试与排错
Wind.js无障碍调试与排错Wind.js无障碍调试与排错
Wind.js无障碍调试与排错
 
JavaScript现代化排错实践
JavaScript现代化排错实践JavaScript现代化排错实践
JavaScript现代化排错实践
 
Jscex:案例、阻碍、体会、展望
Jscex:案例、阻碍、体会、展望Jscex:案例、阻碍、体会、展望
Jscex:案例、阻碍、体会、展望
 
Jscex:案例、经验、阻碍、展望
Jscex:案例、经验、阻碍、展望Jscex:案例、经验、阻碍、展望
Jscex:案例、经验、阻碍、展望
 
The Evolution of Async Programming (GZ TechParty C#)
The Evolution of Async Programming (GZ TechParty C#)The Evolution of Async Programming (GZ TechParty C#)
The Evolution of Async Programming (GZ TechParty C#)
 
Mono for .NET Developers
Mono for .NET DevelopersMono for .NET Developers
Mono for .NET Developers
 
单点登录解决方案的架构与实现
单点登录解决方案的架构与实现单点登录解决方案的架构与实现
单点登录解决方案的架构与实现
 
Documentation Insight技术架构与开发历程
Documentation Insight技术架构与开发历程Documentation Insight技术架构与开发历程
Documentation Insight技术架构与开发历程
 
Windows Phone应用开发心得
Windows Phone应用开发心得Windows Phone应用开发心得
Windows Phone应用开发心得
 
分布式版本管理
分布式版本管理分布式版本管理
分布式版本管理
 
使用.NET构建轻量级分布式框架
使用.NET构建轻量级分布式框架使用.NET构建轻量级分布式框架
使用.NET构建轻量级分布式框架
 
针对iPad平台的高性能网站架构
针对iPad平台的高性能网站架构针对iPad平台的高性能网站架构
针对iPad平台的高性能网站架构
 
企业开发领域的语言特性
企业开发领域的语言特性企业开发领域的语言特性
企业开发领域的语言特性
 
大话程序员可用的算法
大话程序员可用的算法大话程序员可用的算法
大话程序员可用的算法
 
面向对象与生活
面向对象与生活面向对象与生活
面向对象与生活
 
Windows内核技术介绍
Windows内核技术介绍Windows内核技术介绍
Windows内核技术介绍
 
F#语言对异步程序设计的支持
F#语言对异步程序设计的支持F#语言对异步程序设计的支持
F#语言对异步程序设计的支持
 
大众点评网的技术变迁之路
大众点评网的技术变迁之路大众点评网的技术变迁之路
大众点评网的技术变迁之路
 
Better Framework Better Life
Better Framework Better LifeBetter Framework Better Life
Better Framework Better Life
 
如何成为一名优秀的博主
如何成为一名优秀的博主如何成为一名优秀的博主
如何成为一名优秀的博主
 

The Evolution of Async-Programming on .NET Platform (TUP, Full)

  • 1. The Evolution of Async Programming on .NET Platform ZhaoJie @ SNDA Nov, 2010
  • 2. About Me • / / Jeffrey Zhao / • • Blog: http://blog.zhaojie.me/ • Twitter: @jeffz_cn • F#, Scala, JavaScript, Python, .NET, mono... • Java (as the language) hater
  • 3. Agenda • Why & How • .NET 1.0 • .NET 2.0 / C# 2.0 • .NET 3.0 / F# • .NET 4.0 / Reactive Framework • Future / C# vNext
  • 4. Why? Because the essence of Cloud, Web, Mobile is asynchronous computations
  • 5. How? By providing powerful language features / programming model / libraries
  • 7. Two Raw Async Models • Begin/End • Event-based • Both are callback-based • Which is just “asynchronous” means
  • 8. Begin/End Async Model delegate AsyncCallback(IAsyncResult); interface IAsyncResult { object AsyncState { get; } WaitHandle AsyncWaitHandle { get; } bool CompletedSynchronously { get; } bool IsCompleted { get; } } void BeginXxx(arg1, arg2, ..., AsyncCallback, state); TResult EndXxx(IAsyncResult);
  • 9. Let’s write a “Transfer” method in 4 different ways
  • 10. Sync public static void Transfer(string url, Stream streamOut) { var request = WebRequest.Create(url); using (var response = request.GetResponse()) { var streamIn = response.GetResponseStream(); var size = 1024; var buffer = new byte[size]; while (true) { var lengthRead = streamIn.Read(buffer, 0, size); if (lengthRead <= 0) break; streamOut.Write(buffer, 0, lengthRead); } } }
  • 11. Async IAsyncResult BeginTransfer(url, streamOut, ..., callback) { // keep context and BeginGetResponse } void EndGetResponse(...) { // get streamIn and BeginRead } void EndRead(...) { // data read, completed or BeginWrite } void EndWrite(...) { // data wrote, BeginRead }
  • 12. Async 1 IAsyncResult BeginTransfer(url, streamOut, ..., callback) { // keep context and BeginGetResponse } void EndGetResponse(...) { // get streamIn and BeginRead } void EndRead(...) { // data read, completed or BeginWrite } void EndWrite(...) { // data wrote, BeginRead }
  • 13. Async 1 IAsyncResult BeginTransfer(url, streamOut, ..., callback) { // keep context and BeginGetResponse } 2 void EndGetResponse(...) { // get streamIn and BeginRead } void EndRead(...) { // data read, completed or BeginWrite } void EndWrite(...) { // data wrote, BeginRead }
  • 14. Async 1 IAsyncResult BeginTransfer(url, streamOut, ..., callback) { // keep context and BeginGetResponse } 2 void EndGetResponse(...) { // get streamIn and BeginRead } 3 void EndRead(...) { // data read, completed or BeginWrite } void EndWrite(...) { // data wrote, BeginRead }
  • 15. Async 1 IAsyncResult BeginTransfer(url, streamOut, ..., callback) { // keep context and BeginGetResponse } 2 void EndGetResponse(...) { // get streamIn and BeginRead } 3 void EndRead(...) { // data read, completed or BeginWrite } 4 void EndWrite(...) { // data wrote, BeginRead }
  • 16. Async 1 IAsyncResult BeginTransfer(url, streamOut, ..., callback) { // keep context and BeginGetResponse } 2 void EndGetResponse(...) { // get streamIn and BeginRead } 3 void EndRead(...) { // data read, completed or BeginWrite } 5 4 void EndWrite(...) { // data wrote, BeginRead }
  • 17. Async 1 IAsyncResult BeginTransfer(url, streamOut, ..., callback) { // keep context and BeginGetResponse } 2 void EndGetResponse(...) { // get streamIn and BeginRead } 3 void EndRead(...) { // data read, completed or BeginWrite 6 } 5 4 void EndWrite(...) { // data wrote, BeginRead }
  • 18. Robust & Sync public void Transfer(string url, Stream streamOut) { try { var request = WebRequest.Create(url); using (var response = request.GetResponse()) { var streamIn = response.GetResponseStream(); var size = 1024; var buffer = new byte[size]; while (true) { var lengthRead = streamIn.Read(buffer, 0, size); if (lengthRead <= 0) break; streamIn.Write(buffer, 0, lengthRead); } } } catch { // ... } }
  • 19. Robust & Async IAsyncResult BeginTransfer(url, streamOut, ..., callback) { try { ... } catch { ... } } void EndGetResponse(...) { try { ... } catch { ... } } void EndRead(...) { try { ... } catch { ... } } void EndWrite(...) { try { ... } catch { ... } }
  • 20. Event-based Async Model class XxxCompletedEventArgs : EventArgs { Exception Error { get; } TResult Result { get; } } class Worker { event EventHandler<XxxCompletedArgs> XxxCompleted; void XxxAsync(arg1, arg2, ...); }
  • 22. Code Locality is Broken • Used to expressing algorithms linearly • Async requires logical division of algorithms • No if / using / while / for ... • Very difficult to • Combine multiple asynchronous operations • Deal with exceptions and cancellation
  • 23. .NET 2.0 / C# 2.0
  • 24. “yield” for Iterators IEnumerable<int> Numbers() { yield return 0; yield return 1; yield return 2; }
  • 25. “yield” for Iterators IEnumerable<int> Numbers() { MoveNext() yield return 0; yield return 1; yield return 2; }
  • 26. “yield” for Iterators IEnumerable<int> Numbers() { MoveNext() yield return 0; MoveNext() yield return 1; yield return 2; }
  • 27. “yield” for Iterators IEnumerable<int> Numbers() { MoveNext() yield return 0; MoveNext() yield return 1; MoveNext() yield return 2; }
  • 28. “yield” for Iterators IEnumerable<int> Numbers() { MoveNext() yield return 0; MoveNext() yield return 1; MoveNext() yield return 2; MoveNext() }
  • 29. Async with “yield” IEnumerator<int> Transfer(AsyncEnumerator ae, string url, Stream streamOut) { var request = WebRequest.Create(url); request.BeginGetResponse(ae.End(), null); yield return 1; using (var response = request.EndGetResponse(ae.DequeueAsyncResult())) { var streamIn = response.GetResponseStream(); byte[] buffer = new byte[1024]; while (true) { streamIn.BeginRead(buffer, 0, buffer.Length, ae.End(), null); yield return 1; int lengthRead = streamIn.EndRead(ae.DequeueAsyncResult()); if (lengthRead <= 0) break; streamOut.BeginWrite(buffer, 0, lengthRead, ae.End(), null); yield return 1; streamOut.EndWrite(ae.DequeueAsyncResult()); } } }
  • 30. Async with “yield” IEnumerator<int> Transfer(AsyncEnumerator ae, string url, Stream streamOut) { var request = WebRequest.Create(url); request.BeginGetResponse(ae.End(), null); yield return 1; using (var response = request.EndGetResponse(ae.DequeueAsyncResult())) { var streamIn = response.GetResponseStream(); byte[] buffer = new byte[1024]; while (true) { streamIn.BeginRead(buffer, 0, buffer.Length, ae.End(), null); “yield” after yield return 1; firing async operations int lengthRead = streamIn.EndRead(ae.DequeueAsyncResult()); if (lengthRead <= 0) break; streamOut.BeginWrite(buffer, 0, lengthRead, ae.End(), null); yield return 1; streamOut.EndWrite(ae.DequeueAsyncResult()); } } }
  • 31. Async with “yield” IEnumerator<int> Transfer(AsyncEnumerator ae, string url, Stream streamOut) { var request = WebRequest.Create(url); request.BeginGetResponse(ae.End(), null); yield return 1; using (var response = request.EndGetResponse(ae.DequeueAsyncResult())) { var streamIn = response.GetResponseStream(); byte[] buffer = new byte[1024]; while (true) { streamIn.BeginRead(buffer, 0, buffer.Length, ae.End(), null); “yield” after yield return 1; firing async operations int lengthRead = streamIn.EndRead(ae.DequeueAsyncResult()); if (lengthRead <= 0) break; streamOut.BeginWrite(buffer, 0, lengthRead, ae.End(), null); yield return 1; streamOut.EndWrite(ae.DequeueAsyncResult()); continue when } async operations } completed }
  • 32. “yield return” for Async • Coming with new programming patterns • Keep code locality • Good parts: support if / using / while / for ... • But not perfect: cannot use try...catch • The primitives for Fibers - lightweight computation units
  • 34. F# • Language by Don Syme, MS Research • Strongly statically typed language • Functional language with OO ability • For industry and education • Open source (Apache 2.0) • Cross-platform supported by Microsoft
  • 35. Concurrency Challenges • Shared State - Immutability • Code Locality - async { ... } • I/O Parallelism - async { ... } • Scaling to Multi-Machine - Agents with async { ... }
  • 36. What’s async { ... } ... the principle we go by is, don't expect to see a particular concurrency model put into C# because there're many different concurrency model ... it's more about finding things are common to to all kinds of concurrency ... - Anders Hejlsberg
  • 37. Async Workflow async {   let! res = <async work> ... }
  • 38. Async Workflow React! async {   let! res = <async work> ... }
  • 39. Async Workflow React! async {   let! res = <async work> ... } an HTTP Response an UI Event a Timer Callback a Query Response a Web Servcie Response a Disk I/O Completion an Agent Message
  • 40. Async in F# let transferAsync (url: string) (streamOut: Stream) = async { let request = WebRequest.Create(url) use! response = request.AsyncGetResponse() let streamIn = response.GetResponseStream() let rec transferDataAsync (buffer: byte[]) = async { let! lengthRead = streamIn.AsyncRead(buffer, 0, buffer.Length) if lengthRead > 0 then do! streamOut.AsyncWrite(buffer, 0, lengthRead) do! transferDataAsync buffer } do! transferDataAsync (Array.zeroCreate 1024) }
  • 41. Async in F# let transferAsync (url: string) (streamOut: Stream) = async { let request = WebRequest.Create(url) use! response = request.AsyncGetResponse() AsyncGetResponse let streamIn = response.GetResponseStream() let rec transferDataAsync (buffer: byte[]) = async { let! lengthRead = streamIn.AsyncRead(buffer, 0, buffer.Length) AsyncRead if lengthRead > 0 then do! streamOut.AsyncWrite(buffer, 0, lengthRead) AsyncWrite do! transferDataAsync buffer } simply generate from do! transferDataAsync (Array.zeroCreate 1024) Begin/End methods }
  • 42. How async { ... } Works async { let! img = AsyncRead "http://..." printfn "loaded!" do! AsyncWrite img @"c:..." printfn "saved!" }
  • 43. How async { ... } Works async { let! img = AsyncRead "http://..." printfn "loaded!" do! AsyncWrite img @"c:..." printfn "saved!" } = async.Delay(fun -> async.Bind(AsyncRead "http://...", (fun img -> printfn "loaded!" async.Bind(AsyncWrite img @"c:...", (fun () -> printfn "saved!" async.Return())))))
  • 44. F# Async Workflow • Library, not a language feature • Based on Computation Expressions in F# • Support all kinds of language constructions • Error handling: try...catch • Loop: while / for (like “foreach” in C#) • Others: if / use (like “using” in C#), etc. • Easy to • Combine multiple asynchronous operations • Deal with exceptions and cancellation
  • 45. F# Resources http://fsharp.net Programming F# Expert F# 2.0 Real World FP
  • 46. .NET 4.0 / Reactive Framework
  • 47. Reactive Framework Fundamentally change the way you think about coordinating and orchestrating asynchronous and event-based programming
  • 48. How By showing that asynchronous and event-base computations are just push-based collections
  • 49. Interactive Reactive Environment Program
  • 50. Enumerable Collections interface IEnumerable<out T> { IEnumerator<T> GetEnumerator(); } interface IEnumerator<out T> { bool MoveNext(); T Current { get; } }
  • 52. Observable Collections interface IObservable<out T> { IDisposable Subscribe(IObserver<T> o) } interface IObserver<in T> { void OnCompleted(); void OnNext(T item); void OnError(Exception ex); }
  • 53. IEnumerable & IEnumerator are prototypical interfaces for interactive collections and interactive programs. IObservable & IObserver are prototypical interfaces for observable collections and reactive, asynchronous & event-based programs.
  • 54. LINQ to Observable If you are writing LINQ or declarative code in an interactive program...
  • 55. LINQ to Observable If you are writing LINQ or declarative code in an interactive program... You already know how to use it!
  • 56. Again ... the principle we go by is, don't expect to see a particular concurrency model put into C# because there're many different concurrency model ... it's more about finding things are common to to all kinds of concurrency ... - Anders Hejlsberg
  • 57. Again ... the principle we go by is, don't expect to see a particular concurrency model put into C# because there're many different concurrency model ... it's more about finding things are common to to all kinds of concurrency ... - Anders Hejlsberg
  • 58. Move by WASD // filter the KeyPress events when playing var keyPress = GetKeyPress().Where(_ => isPlaying); // filter the events to move left var moveLeft = from ev in keyPress where ev.EventArgs.KeyChar == 'a' where ball.Left > 0 select ev; moveLeft.Subscribe(_ => ball.Left -= 5); // filter the events to move top var moveTop = from ev in keyPress where ev.EventArgs.KeyChar == 'w' where ball.Top > 0 select ev; moveTop.Subscribe(_ => ball.Top -= 5);
  • 59. Mouse Drag and Draw var mouseMove = GetMouseMove(); var mouseDiff = mouseMove.Zip(mouseMove.Skip(1), (prev, curr) => new { PrevPos = new Point( prev.EventArgs.X, prev.EventArgs.Y), CurrPos = new Point( curr.EventArgs.X, curr.EventArgs.Y) }); var mouseDrag = from _ in GetMouseDown() from diff in mouseDiff.TakeUntil(GetMouseUp()) select diff; mouseDrag.Subscribe(d => DrawLine(d.PrevPos, d.CurrPos));
  • 60. Everything in Web is Asynchronous • User actions • AJAX requests • Animations • ...
  • 61. Rx in JavaScript • A full featured port for JavaScript • Easy-to-use conversions from existing DOM, XmlHttpRequest, etc • In a download size of less than 7kb (gzipped) • Bindings for various libraries / frameworks • jQuery • MooTools • Dojo • ...
  • 62. Drag and Draw in JS var target = $("#paintPad"); var mouseMove = target.toObservable("mousemove"); var mouseDiff = mouseMove.Zip(mouseMove.Skip(1), function(prev, curr) { return { prevPos: { x: prev.clientX, y: prev.clientY }, currPos: { x: curr.clientX, y: curr.clientY } }; }); var mouseDown = target.toObservable("mousedown"); var mouseUp = target.toObservable("mouseup"); var mouseDrag = mouseDown.SelectMany(function() { mouseDiff.TakeUntil(mouseUp); }); mouseDrag.Subscribe( function(d) { drawLine(d.prevPos, d.currPos); });
  • 63. Wikipedia Lookup var textBox = $("#searchInput"); var searcher = textBox .toObservable("keyup") .Throttle(500) .Select(function(_) { return textBox.val(); }) .Select(function(term) { return queryWikipedia(term); }) .Switch(); searcher.Subscribe( function(data) { var results = $("#results"); results.empty(); $.each(data, function(_, value) { results.append($("<li/>").text(value)); }); }, function(error) { $("#error").html(error); });
  • 64. Time Flies like an Arrow var container = $("#container"); var mouseMove = container.toObservable("mousemove"); for (var i = 0; i < text.length; i++) { (function(i) { var ele = $("<span/>").text(text.charAt(i)); ele.css({position: "absolute"}).appendTo(container); mouseMove.Delay(i * 100).Subscribe(function (ev) { ele.css({ left: ev.clientX + i * 20 + 15 + "px", top: ev.clientY + "px" }); }); })(i);
  • 65. Benefits of Rx • Easy to composite and coordinate async operations • Express the algorithm in functional ways • Helper method: For / While / If / Try / Switch... • Easy to be unit tested • ...
  • 66. Rx & Language Features • Features in C# that Rx uses • Extension method • Lambda expression & closure • Type inference • LINQ query expression • Rx has been implemented in ... • C# & VB • JavaScript • F#
  • 67. Portability • Rx can be easily ported to various languages • Scala • Ruby • Python • modern languages with basic functional features • Almost impossible to implement Rx in Java • Cannot extend a type without breaking code • Missing enough functional features
  • 68. Rx Resources • Matthew Podwysocki • http://codebetter.com/blogs/matthew.podwysocki/ • Reactive Framework on MSDN DevLabs • http://msdn.microsoft.com/en-us/devlabs/ ee794896.aspx • Tomáš Petříček • http://tomasp.net/
  • 69. Comparison • F# Async Workflow • Elegant, simple, easy to use • Can only be used at server-side (WebSharper come to rescure?) • Reactive Framework • Can be used at both server-side and client-side. • New async model brings learning cost.
  • 70. Out of Topic Can we programming like F# in JavaScript?
  • 71. Jscex & Jscex.Async • Computation Expressions and Async Workflow implemented in JavaScript • http://github.com/jeffreyzhao/jscex
  • 72. Clock var drawClockAsync = eval(Jscex.compile("$async", function(interval) { while (true) { drawClock(new Date()); $await(Jscex.Async.sleep(interval)); } } )); Jscex.Async.start(drawClockAsync(1000));
  • 73. Animation var moveAsync = eval(Jscex.compile("$async", function(e, start, end, duration) { for (var t = 0; t < duration; t += 50) { e.style.left = start.x + (end.x - start.x) * t / duration; e.style.top = start.y + (end.y - start.y) * t / duration; $await(Jscex.Async.sleep(50)); } e.style.left = end.x; e.style.top = end.y; } )); var moveSquareAsync = eval(Jscex.compile("$async", function(e) { $await(moveAsync(e, {x:100, y:100}, {x:400, y:100}, 1000)); $await(moveAsync(e, {x:400, y:100}, {x:400, y:400}, 1000)); $await(moveAsync(e, {x:400, y:400}, {x:100, y:400}, 1000)); $await(moveAsync(e, {x:100, y:400}, {x:100, y:100}, 1000)); }));
  • 75. Source async Task<XElement> GetRssAsync(string url) { var client = new WebClient(); var task = client.DownloadStringTaskAsync(url); var text = await task; var xml = XElement.Parse(text); return xml; }
  • 76. Compiled Task<XElement> GetRssAsync(string url) { var $builder = AsyncMethodBuilder<XElement>.Create(); var $state = 0; TaskAwaiter<string> $a1; Action $resume = delegate { try { if ($state == 1) goto L1; var client = new WebClient(); var task = client.DownloadStringTaskAsync(url); $state = 1; $a1 = task.GetAwaiter(); if ($a1.BeginAwait($resume)) return; L1: var text = $a1.EndAwait(); var xml = XElement.Parse(text); $builder.SetResult(xml); } catch (Exception $ex) { $builder.SetException($ex); } }; $resume(); return $builder.Task; }
  • 77. Conclusion • Async Programming is difficult • New programming language / feature / library / model can help
  • 78. Q &A