2. 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.
3. 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
4. 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.
5. .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
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
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
9. 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 )
10. 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);
}
}
12. 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
13. 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); }
}
} }
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 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
19. 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
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()
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.
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
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.
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.