C# 5.0 Async
 Pratik Khasnabis
DDD Melbourne 2012
About Me

Quick background
Lead Developer at Bupa Australia
Developer for 15 years
C# & .Net 8 years
C++ before that




Disclaimer
This presentation is my own and I do not
represent my company.
The need for Async

Responsive UI
UI thread is running as a message pump in a   Touch ready Metro Apps
loop                                          In WinRT if an API is likely to take
Waiting on IO or long computation will stop   more than 50ms to run the API is
message processing => Frozen UI               asynchronous




Scalable Server Applications
A CLR thread is used to service requests
A blocked thread => less scalable
Service thousands of IO bound requests on a
small pool of threads
Async in .Net 4.5

First introduced in PDC
                                   Two new keywords
2010 and the refresh in
                                   async and await
MIX 2011 (VS 2010 SP1)



An unsupported out-of-             Built to take advantage of
band release. Updated C#                Task and Task<T>
and VB compilers.                   Introduced in .Net 4.0




AsyncCtpLibrary.dll
                                       Async methods
introduced async
                                     Pervasive in .Net 4.5
extension methods for
common classes.
.NET 4 and Silverlight 5
Async Targeting Pack
Download using NuGet
Microsoft.CompilerServices.AsyncTargetingPack




Differences in Behaviour
Read the release notes
Static helper methods are in TaskEx
class instead of Task
e.g. Task.Run(…) vs TaskEx.Run(…)               Windows Phone and Azure
                                                No support yet
Task

Task                                Awaiters
A Task is promise of a              Tasks are the backing
result that will delivered          types for async methods
at some time in future              in .Net 4.5




Compositional                       Two types
Tasks can be composed               Task
using continuations                 Task<T>



                                    Awaiters
Cancellable                         Tasks are the backing
Tasks can be designed to            types for async methods
be cancelled easily                 in .Net 4.5
Async and Await

Keyword: async                           Keyword: await
Only methods or lamdbas with async       Makes the rest of method a
modifier can use the await keyword.      continuation
Return type must be void, Task or        When the method completes
Task<T>                                  execution resumes where it left off on
The method actually returns void or T,   the right synchronisation context
the compile creates the Task object      Compiler generates a state machine
Doesn’t make the method
asynchronous


                                         var awaiter = expression.GetAwaiter();
                                         if (awaiter.IsCompleted)
                                           Console.WriteLine (awaiter.GetResult());
                                         else
var result = await expression;
                                           awaiter.OnCompleted (() =>
<code block>                               {
                                             var result = awaiter.GetResult();
                                             <code block>
                                           );
Task-Based Async Pattern

TAP methods has an async modifier ,
                                      TAP methods should return quickly to
returns a running Task or
                                      caller with a small synchronous
Task<TResult> and ends with an
                                      phase.
“Async” suffix by convention



 TAP methods should have the same
 parameters as the synchronous one    Avoids out and ref parameters
 in the same order




Can have CancellationToken
                                      Can have IProgress<T> parameter
parameter
Async in .Net 4.5 BCL

System.Xml.XmlReader
                                       System.Net.Mail
public virtual Task<bool>
                                       public Task SendMailAsync(
ReadAsync()
                                       MailMessage message )


                                      System.Net.Http.HttpClient
System.IO.Stream                      public Task<string>
public Task CopyToAsync(              GetStringAsync( string
Stream destination )                  requestUri )


                            System.Net.WebSockets
                            public abstract
System.IO.TextReader        Task<WebSocketReceiveResult>
public virtual Task<int>    ReceiveAsync( ArraySegment<byte>
ReadAsync( char[] buffer,   buffer, CancellationToken
int index, int count )      cancellationToken )
Async in WPF/WinForms apps
 Caller         Void Async Method                           Task Async Method                     Awaitable
UI
                                                                                                       IOCP
thread
                                                                                                       thread
          async void
          LoadPhotosAsync(string tag)
          {                                         async Task<FlickrPhoto[]>
           …                                        GetPhotosAsync(string tag, int page)
          var photosTask = GetPhotosAsync(tag, pa   {
          ge);
                                                    WebClient client = new WebClient();

                                                    var webTask = client.DownloadStringTaskAsyn   webTask
                                                    c(…);
                                                    var apiResponse = await webTask;

          var photos = await photosTask;

                                                    var photos = ParseResponse(apiResponse);
                                                    return photos;
          DisplayPhotos(photos);



                                                    }

          }
Concurrency without threads

             UI Thread



Download                         Process
                Message Pump
  Data                            Data



             Process UI Events
Async in Server Apps
                                Thread Pool Exhaustion



                                                                   DB
                                              ASP.Net
             IIS      IIS I/O Thread
           Worker
           Process
                                                                   WS


                      MaxConcurrentRequestsPerCPU


                                             Worker Threads        File
                                             Waiting for I/O ops
                     HTTP.SYS
                     Kernel
                                             To complete
                     Queue
HTTP
Requests
ASP.Net Core Services

Asynchronous HTTP modules                                 Asynchronous HTTP handlers
public class MyHttpModule : IHttpModule
{                                                         public class MyAsyncHandler :
private async Task
ScrapeHtmlPage(object caller, EventArgs e)                HttpTaskAsyncHandler
{                                                         {
 await ...
}                                                           public override async Task
  public void Init(HttpApplication                        ProcessRequestAsync(HttpContext
context)
 {                                                        context)
   EventHandlerTaskAsyncHelper helper =                     {
   new EventHandlerTaskAsyncHelper(ScrapeHtmlPage);
   context.AddOnPostAuthorizeRequestAsync(                    await …
     helper.BeginEventHandler, helper.EndEventHandler);     }
 }
}                                                         }
ASP.Net MVC 4
                                  Timeout
Controller                        [AsyncTimeout(2000)]
Derive from AsyncController ??    [HandleError(ExceptionType =
                                  typeof(TaskCanceledException), View
                                  = "TimedOut")]



Actions
async methods returning Task or
Task<ActionResult>
ASP.Net WebForms
        Page Markup
        <%@ Page Language="C#"
        Async="true" AsyncTimeOut="2"
        CodeBehind="AsyncPage.aspx.cs" %>


        Page_Load method
        Register the async method
        The async mehtod will be
        asynchronoiusly executed after
        PreRender stage in page lifecycle
WCF
Service: Async operations                            Client: Async proxies
[ServiceContract]                                    Use svcutil or Add Service Reference
public interface IDemoService
{
  [OperationContract]                                var proxy = new
  Task<string> GetStockQuoteAsync(string ticker);    StockQuoteService.StockQuoteSoapClie
}
                                                     nt();
public class DemoService : IDemoService              var quote = await
{                                                    proxy.GetQuoteAsync("MSFT");
  public async Task<string> GetStockQuoteAsync
(string ticker)
  {
    await ...
  }
}
VS 2012 Unit Tests
Async Test Methods – return Task     Test Frameworks
[TestMethod]                         MS Test – Supports async, Built in test
public async Task UnitTestMethod()   provider
{                                    xUnit – Supports async in v1.9,
  await Task.Delay(1000);            downloadable test provider
  Assert.AreEqual(1,1);              NUnit – Doesn’t support async,
}                                    downloadable test provider


Execution Time
1 sec
Metro and WinRT
http://blogs.msdn.com/b/windowsappdev/archive/2012/06/14/exposing-net-tasks-
as-winrt-asynchronous-operations.aspx
http://blogs.msdn.com/b/windowsappdev/archive/2012/03/20/keeping-apps-fast-
and-fluid-with-asynchrony-in-the-windows-runtime.aspx
http://blogs.msdn.com/b/windowsappdev/archive/2012/04/24/diving-deep-with-
winrt-and-await.aspx
                                 Watch the other
                                 sessions on Metro
IAsyncInfo                       App Development
All async methods in WinRT
implements this interface and 4 other                               Compiler Magic
IAsyncAction                                    IAsyncInfo has the awaitable pattern
IAsyncOperation<TResult>                         The C# and VB compiler will convert
IAsyncActionWithProgress<TProgress>            WinRT async methods to return Tasks
IAsyncOperationWithProgress<TResult,
TProgress>
Choosing Sync vs Async

            Synchronous
Operations are simple or short-running
        CPU bound operations
    Simplicity is more important




                                                        Asynchronous
                                         I/O bound operations (DB, network, disk)
                                               Provide cancellation support
                                               Parallelism is more important
ADO.Net
                                     Tabular Data Stream Protocol
Worker
Thread
                                           reader.NextResult()

               i/o                                         “DONE”                      “DONE”
                                          Result Set        Token     Result Set        Token


                               reader.Next()

         i/o         “ROW”                             “ROW”                       “ROW”
                      Token          Row                Token       Row             Token



                              Reader.IsDBNull()
         i/o
                     Column          Column            Column       Column         Column
                     Header           Data             Header        Data          Header

                                pa   ck     et    s


                       Large Column e.g. varbinary(8000)
ADO.Net
                               Recommendations


Use
                                        Use
CommandBehavior.SequentialAccess
                                        NextResultAsync() and ReadAsync()
Unless reading large columns


Use
Synchronous column access               Use
IsDBNull, GetFieldValue<T>              Streaming for massive columns
Unless reading large columns            GetStream()
IsDBNullAsync,                          GetTextReader()
GetFieldValueAsync<T>                   GetXmlReader()
Resources
• http://msdn.microsoft.com/en-US/async
• VB.Net - http://blogs.msdn.com/b/lucian/
• C# (implementation details) -
  https://msmvps.com/blogs/jon_skeet/archive
  /tags/Eduasync/default.aspx

Async Programming in C# 5

  • 1.
    C# 5.0 Async Pratik Khasnabis DDD Melbourne 2012
  • 2.
    About Me Quick background LeadDeveloper at Bupa Australia Developer for 15 years C# & .Net 8 years C++ before that Disclaimer This presentation is my own and I do not represent my company.
  • 3.
    The need forAsync Responsive UI UI thread is running as a message pump in a Touch ready Metro Apps loop In WinRT if an API is likely to take Waiting on IO or long computation will stop more than 50ms to run the API is message processing => Frozen UI asynchronous Scalable Server Applications A CLR thread is used to service requests A blocked thread => less scalable Service thousands of IO bound requests on a small pool of threads
  • 4.
    Async in .Net4.5 First introduced in PDC Two new keywords 2010 and the refresh in async and await MIX 2011 (VS 2010 SP1) An unsupported out-of- Built to take advantage of band release. Updated C# Task and Task<T> and VB compilers. Introduced in .Net 4.0 AsyncCtpLibrary.dll Async methods introduced async Pervasive in .Net 4.5 extension methods for common classes.
  • 5.
    .NET 4 andSilverlight 5 Async Targeting Pack Download using NuGet Microsoft.CompilerServices.AsyncTargetingPack Differences in Behaviour Read the release notes Static helper methods are in TaskEx class instead of Task e.g. Task.Run(…) vs TaskEx.Run(…) Windows Phone and Azure No support yet
  • 6.
    Task Task Awaiters A Task is promise of a Tasks are the backing result that will delivered types for async methods at some time in future in .Net 4.5 Compositional Two types Tasks can be composed Task using continuations Task<T> Awaiters Cancellable Tasks are the backing Tasks can be designed to types for async methods be cancelled easily in .Net 4.5
  • 7.
    Async and Await Keyword:async Keyword: await Only methods or lamdbas with async Makes the rest of method a modifier can use the await keyword. continuation Return type must be void, Task or When the method completes Task<T> execution resumes where it left off on The method actually returns void or T, the right synchronisation context the compile creates the Task object Compiler generates a state machine Doesn’t make the method asynchronous var awaiter = expression.GetAwaiter(); if (awaiter.IsCompleted) Console.WriteLine (awaiter.GetResult()); else var result = await expression; awaiter.OnCompleted (() => <code block> { var result = awaiter.GetResult(); <code block> );
  • 8.
    Task-Based Async Pattern TAPmethods has an async modifier , TAP methods should return quickly to returns a running Task or caller with a small synchronous Task<TResult> and ends with an phase. “Async” suffix by convention TAP methods should have the same parameters as the synchronous one Avoids out and ref parameters in the same order Can have CancellationToken Can have IProgress<T> parameter parameter
  • 9.
    Async in .Net4.5 BCL System.Xml.XmlReader System.Net.Mail public virtual Task<bool> public Task SendMailAsync( ReadAsync() MailMessage message ) System.Net.Http.HttpClient System.IO.Stream public Task<string> public Task CopyToAsync( GetStringAsync( string Stream destination ) requestUri ) System.Net.WebSockets public abstract System.IO.TextReader Task<WebSocketReceiveResult> public virtual Task<int> ReceiveAsync( ArraySegment<byte> ReadAsync( char[] buffer, buffer, CancellationToken int index, int count ) cancellationToken )
  • 10.
    Async in WPF/WinFormsapps Caller Void Async Method Task Async Method Awaitable UI IOCP thread thread async void LoadPhotosAsync(string tag) { async Task<FlickrPhoto[]> … GetPhotosAsync(string tag, int page) var photosTask = GetPhotosAsync(tag, pa { ge); WebClient client = new WebClient(); var webTask = client.DownloadStringTaskAsyn webTask c(…); var apiResponse = await webTask; var photos = await photosTask; var photos = ParseResponse(apiResponse); return photos; DisplayPhotos(photos); } }
  • 11.
    Concurrency without threads UI Thread Download Process Message Pump Data Data Process UI Events
  • 12.
    Async in ServerApps Thread Pool Exhaustion DB ASP.Net IIS IIS I/O Thread Worker Process WS MaxConcurrentRequestsPerCPU Worker Threads File Waiting for I/O ops HTTP.SYS Kernel To complete Queue HTTP Requests
  • 13.
    ASP.Net Core Services AsynchronousHTTP modules Asynchronous HTTP handlers public class MyHttpModule : IHttpModule { public class MyAsyncHandler : private async Task ScrapeHtmlPage(object caller, EventArgs e) HttpTaskAsyncHandler { { await ... } public override async Task public void Init(HttpApplication ProcessRequestAsync(HttpContext context) { context) EventHandlerTaskAsyncHelper helper = { new EventHandlerTaskAsyncHelper(ScrapeHtmlPage); context.AddOnPostAuthorizeRequestAsync( await … helper.BeginEventHandler, helper.EndEventHandler); } } } }
  • 14.
    ASP.Net MVC 4 Timeout Controller [AsyncTimeout(2000)] Derive from AsyncController ?? [HandleError(ExceptionType = typeof(TaskCanceledException), View = "TimedOut")] Actions async methods returning Task or Task<ActionResult>
  • 15.
    ASP.Net WebForms Page Markup <%@ Page Language="C#" Async="true" AsyncTimeOut="2" CodeBehind="AsyncPage.aspx.cs" %> Page_Load method Register the async method The async mehtod will be asynchronoiusly executed after PreRender stage in page lifecycle
  • 16.
    WCF Service: Async operations Client: Async proxies [ServiceContract] Use svcutil or Add Service Reference public interface IDemoService { [OperationContract] var proxy = new Task<string> GetStockQuoteAsync(string ticker); StockQuoteService.StockQuoteSoapClie } nt(); public class DemoService : IDemoService var quote = await { proxy.GetQuoteAsync("MSFT"); public async Task<string> GetStockQuoteAsync (string ticker) { await ... } }
  • 17.
    VS 2012 UnitTests Async Test Methods – return Task Test Frameworks [TestMethod] MS Test – Supports async, Built in test public async Task UnitTestMethod() provider { xUnit – Supports async in v1.9, await Task.Delay(1000); downloadable test provider Assert.AreEqual(1,1); NUnit – Doesn’t support async, } downloadable test provider Execution Time 1 sec
  • 18.
    Metro and WinRT http://blogs.msdn.com/b/windowsappdev/archive/2012/06/14/exposing-net-tasks- as-winrt-asynchronous-operations.aspx http://blogs.msdn.com/b/windowsappdev/archive/2012/03/20/keeping-apps-fast- and-fluid-with-asynchrony-in-the-windows-runtime.aspx http://blogs.msdn.com/b/windowsappdev/archive/2012/04/24/diving-deep-with- winrt-and-await.aspx Watch the other sessions on Metro IAsyncInfo App Development All async methods in WinRT implements this interface and 4 other Compiler Magic IAsyncAction IAsyncInfo has the awaitable pattern IAsyncOperation<TResult> The C# and VB compiler will convert IAsyncActionWithProgress<TProgress> WinRT async methods to return Tasks IAsyncOperationWithProgress<TResult, TProgress>
  • 19.
    Choosing Sync vsAsync Synchronous Operations are simple or short-running CPU bound operations Simplicity is more important Asynchronous I/O bound operations (DB, network, disk) Provide cancellation support Parallelism is more important
  • 20.
    ADO.Net Tabular Data Stream Protocol Worker Thread reader.NextResult() i/o “DONE” “DONE” Result Set Token Result Set Token reader.Next() i/o “ROW” “ROW” “ROW” Token Row Token Row Token Reader.IsDBNull() i/o Column Column Column Column Column Header Data Header Data Header pa ck et s Large Column e.g. varbinary(8000)
  • 21.
    ADO.Net Recommendations Use Use CommandBehavior.SequentialAccess NextResultAsync() and ReadAsync() Unless reading large columns Use Synchronous column access Use IsDBNull, GetFieldValue<T> Streaming for massive columns Unless reading large columns GetStream() IsDBNullAsync, GetTextReader() GetFieldValueAsync<T> GetXmlReader()
  • 22.
    Resources • http://msdn.microsoft.com/en-US/async • VB.Net- http://blogs.msdn.com/b/lucian/ • C# (implementation details) - https://msmvps.com/blogs/jon_skeet/archive /tags/Eduasync/default.aspx

Editor's Notes

  • #5 http://blogs.msdn.com/b/somasegar/archive/2010/10/28/making-asynchronous-programming-easy.aspxWith Async, our goal now is to make asynchronous programming far more approachable so asynchronous code is as easy to write and maintain as synchronous code. Making your code asynchronous should require only simple changes and should be possible to implement in a non-disruptive manner in your code. At the same time, it should be evident when code is “going async” so that the inherently-concurrent nature of the method can be understood at a glance.
  • #7 http://en.wikipedia.org/wiki/Hollywood_principleThreads are too low levelThreads are not the answerThread creation is expensiveEach managed thread takes 1MB of stack spaceContext switching is expensiveWriting asynchronous methods is difficultUsing callbacks for continuationsError handling, Cancellation, Progress Reporting is complicatedDoesn’t feel natural
  • #8 Asynchronous operations can share a single thread for multiple control flowsThe UI and IOCP threads are provided by the CLR or OS – reuseCo-Operative multitasking. Wait for tasks to finish and yield control flow while awaiting.
  • #13 http://msdn.microsoft.com/en-us/library/ee728598.aspxOn the Web server, the .NET Framework maintains a pool of threads that are used to service ASP.NET requests. When a request arrives, a thread from the pool is dispatched to process that request. If the request is processed synchronously, the thread that processes the request is blocked while the request is being processed, and that thread cannot service another request. If all available threads might be blocked. This condition is known as thread starvation. When this condition is reached, the Web server queues requests. If the request queue becomes full, the Web server rejects requests with an HTTP 503 status (Server Too Busy). However, during an asynchronous call, the server is not blocked from responding to other requests while it waits for the first request to complete. Therefore, asynchronous requests prevent request queuing when there are many requests that invoke long-running operations.When an asynchronous action is invoked, the following steps occur:1. The Web server gets a thread from the thread pool (the worker thread) and schedules it to handle an incoming request. This worker thread initiates an asynchronous operation.2. The worker thread is returned to the thread pool to service another Web request.3. When the asynchronous operation is complete, it notifies ASP.NET.4. The Web server gets a worker thread from the thread pool (which might be a different thread from the thread that started the asynchronous operation) to process the remainder of the request, including rendering the response.http://blogs.msdn.com/b/tmarq/archive/2007/07/21/asp-net-thread-usage-on-iis-7-0-and-6-0.aspx in IIS 7.5 and 7.0 integrated mode, ASP.NET restricts the number of concurrently executing requests. Obviously if the reqeusts are synchronous, then the number of concurrently executing requests is the same as the number of threads concurrently executing requests, but if the requests are asynchronous then these two numbers can be quite different as you could have far more requests than threads.
  • #14 http://www.asp.net/vnext/overview/whitepapers/whats-new
  • #15 http://msdn.microsoft.com/en-us/library/hh420390(v=vs.110).aspx
  • #16 http://msdn.microsoft.com/en-us/library/gg416514(v=vs.108).aspxhttp://blogs.msdn.com/b/nicd/archive/2007/04/16/dissection-of-an-asp-net-2-0-request-processing-flow.aspx
  • #21 http://blogs.msdn.com/b/adonet/archive/2012/04/20/using-sqldatareader-s-new-async-methods-in-net-4-5-beta.aspxhttp://blogs.msdn.com/b/adonet/archive/2012/07/15/using-sqldatareader-s-new-async-methods-in-net-4-5-beta-part-2-examples.aspx
  • #22 In roadmap for Entity Framework 6http://msdn.microsoft.com/en-us/library/hh556234(v=vs.110).aspx