training – going async

49
GOING ASYNC THERE IS NO THREAT MAXIME LEMAITRE – 29/10/14

Upload: betclic-everest-group-tech-team

Post on 02-Jul-2015

1.529 views

Category:

Software


4 download

DESCRIPTION

Since the introduction of C#, async/await concepts are still misunderstood by many developers. Async programming tries to solve three problems (Offloading, Concurrency, Scalability) in a mean abstraction. This presentation is a good starting point to asynchronous programming in .net. There are many links and references, so do not hesitate to go deeper.

TRANSCRIPT

Page 1: Training – Going Async

GOING ASYNCTHERE IS NO THREAT

MAXIME LEMAITRE – 29/10/14

Page 2: Training – Going Async

Agenda

• Introduction• Brief History• Refresher of the TPL• What’s different since 4.5 ?• Best Practices• Working with Async

Asynchronous programming is a means of parallel programming in which a unit of work runs separately from the main application thread and notifies the calling thread of its completion, failure or progress. Why do we need it now ?

Page 3: Training – Going Async

Dangers of Synchronous programming

Client-Side Server-Side

Page 4: Training – Going Async

What does asynchrony really mean?

SynchronousPerform something here and now.I’ll regain control to execute something else when it’s done.

AsynchronousInitiate something here and now.I’ll regain control to execute something else “immediately”.

How an operation is invokedimplies nothing about the

implementation of the workload itself.

Async Clinic

Page 5: Training – Going Async

Sync vs Async

“Pause for 10 seconds, then output 'Hello' to the console.”

Synchronous

Both “async over sync” and “sync over async” can be problematicif you don’t completely understand the implementation.

Asynchronous

Page 6: Training – Going Async

Why go Async ?

Page 7: Training – Going Async

Going Asyncpublic class MyClass { public int Read(byte [] buffer, int offset, int count); }

public class MyClass { public Task<int> ReadAsync(byte [] buffer, int offset, int count); }

10 years

1.0 (2002)

4.5 (2012)

Page 8: Training – Going Async

• Introduced in .net 1.1 (no async support before)• Asynchronous operations require BeginXX and EndXX methods

– Example : BeginWrite and EndWrite for asynchronous write operations).

• No longer recommended

• Several APIs and legacy code still use this pattern

Asynchronous Programming Model (APM)http://msdn.microsoft.com/en-us/library/ms228963.aspx

public class MyClass { public IAsyncResult BeginRead( byte [] buffer, int offset, int count, AsyncCallback callback, object state); public int EndRead(IAsyncResult asyncResult); }

Page 9: Training – Going Async

• Introduced in .net 2.0• Requires a method that has the Async suffix, and also requires

one or more events, event handler delegate types, and EventArg-derived types.

Event-based Asynchronous Pattern (EAP)http://msdn.microsoft.com/en-us/library/ms228969.aspx

public class MyClass { public void ReadAsync(byte [] buffer, int offset, int count); public event ReadCompletedEventHandler ReadCompleted; } public delegate void ReadCompletedEventHandler( object sender, ReadCompletedEventArgs eventArgs); public class ReadCompletedEventArgs : AsyncCompletedEventArgs { public int Result { get; } }

Page 10: Training – Going Async

• Introduced in .net 4.0 but greatly improved in 4.5• Uses a single method to represent the initiation and

completion of an asynchronous operation.• Recommended approach to asynchronous programming in

the .NET Framework.• Very similar to the synchronous version• Interop with Other Asynchronous Patterns and Types is

supported (EAP<>TAP, APM<>TAP)

Task-based Asynchronous Pattern (TAP)http://msdn.microsoft.com/en-us/library/hh873175.aspx

public class MyClass { public Task<int> ReadAsync(byte [] buffer, int offset, int count); }

Page 11: Training – Going Async

Refresher on the TPLWhat is a Task/Task<> ?

Page 12: Training – Going Async

What is a Task/Task<> ?• A Task represents an asynchronous operation

– resembles a thread or ThreadPool work item, but at a higher level of abstraction

– Similar to promises in Javascript

• Task can only run from start to finish once– you cannot run the same task object two times. Have to create another Task object for

running the same code

• More efficient and more scalable use of system resources.– Tasks are queued to the ThreadPool, which has been enhanced with algorithms that

determine and adjust to the number of threads and that provide load balancing to maximize throughput. This makes tasks relatively lightweight, and you can create many of them to enable fine-grained parallelism.

• More programmatic control than is possible with a thread or work item.– Rich set of APIs that support waiting, cancellation, continuations, robust exception

handling, detailed status, custom scheduling, and more.

• Task (as it is used by the TPL) is pretty much completely different than Task (as it is used by async).

TPL is the preferred API for writing multi-threaded, asynchronous, and parallel code

Page 13: Training – Going Async

Task<T> Properties

Task<T> has important properties. Don’t reinvent the wheel when consuming Task and Task<T> !

Page 14: Training – Going Async

Starting a Task

Task.Run vs Task.Factory.StartNew

• Threre are many ways to start a task.

• Most of time, we don’t need to start a Task by yourself ; The API/Framework method will give a task.– eg HttpClient, StreamReader, …

• If you still need to start a Task, use– Task.Run

– Task.Factory.StartNew for a full control

• About Task.Run– Do not use it just to “provide something

awaitable” aka a fake-asynchronous method

– CPU-bound tasks only

Page 15: Training – Going Async

Cancelling a Task

• Cancellation is supported through the use of CancellationToken (via CancellationTokenSource ) to requestcancellation

• You can terminate an operation– By returning the delegate (In the case the

status is RantoCompletion and not Canceled)

– By throwing a OperationCanceledException via ThrowIfCancellationRequested

• Cancellation token are present in all async API

Task Cancellation

Page 16: Training – Going Async

Exceptions handling

• User-code can throw intentionally (or not any) any kind of exceptions.

• Exceptions are propagated back to the joining code when using Task.Wait(), Task.Result,await …– Be sure to always surround this with a

try/catch statement

• Task infrastructure wraps thrownexceptions in AggregateExceptioninstance. In that case, the task status is Faulted and Task.Exception contains

Read more on TPL and Exceptions

Page 17: Training – Going Async

Task Continuations

• A continuation task is an asynchronous task that is invoked by another task– Traditionally, this has been done by using callback methods

• Continuations are relatively easy to use, but are nevertheless very powerful and flexible. For example, you can:– pass data from the antecedent to the continuation

– specify the conditions under which the continuation will be invoked or not invoked

– cancel a continuation either before it starts or cooperatively as it is running

– invoke multiple continuations from the same antecedent

– invoke one continuation when all or any one of multiple antecedents complete

– chain continuations one after another to any arbitrary length

– use a continuation to handle exceptions thrown by the antecedent

– …

• Many continuations options (NotOnFaulted, OnlyOnFaulted, ..)

• Continuation Tasks is an important topic to achieve « Async all the way »

Continuation Tasks

Page 18: Training – Going Async

Task ContinuationExamples

Page 19: Training – Going Async

What’s differentsince .net 4.5 ?

Page 20: Training – Going Async

What’s different now ?

Asynchronous programming with .NET 4 is a little easier.

Asynchronous programming with .NET 4.5 is a lot easier.

Page 22: Training – Going Async

TPL at the Core layer

Application area Supporting APIs that contain async methods

Web access HttpClient , SyndicationClient

Working with files StorageFile, StreamWriter, StreamReader, XmlReader

Working with images MediaCapture, BitmapEncoder, BitmapDecoder

WCF programming Synchronous and Asynchronous Operations

Asynchrony is essential for activities that are potentially blocking, ; so async programming was added in several APIs from the .NET Framework 4.5 and the Windows Runtime

Page 23: Training – Going Async

New Task Methods

• Task.Run : Use it to offload work as a Task or Task<TResult> to the thread pool

• Task.Delay : Use the Delay method to introduce pauses into an asynchronous method’s execution

• Task.FromResult : Use the FromResult<TResult> method in scenarios where data may already be available and just needs to be returned from a task-returning method lifted into a Task<TResult>:

• Task.WhenAll : Use the WhenAll method to asynchronously wait on multiple asynchronous operations that are represented as tasks

• Task.WhenAny : Use the WhenAny method to asynchronously wait for just one of multiple asynchronous operations represented as tasks to complete

• …

Page 24: Training – Going Async

New keywords : async/awaitadded in .net 4.5 & C# 5

• Allow writing/debugging async code almost as if it is a usual synchronous code

• Both keywords - async and await - always work together.– await without async is not allowed.

– async without await is allowed, but not the method executes as a synchronous method

Use the async modifier to specify that a method, lambda expression, or anonymous method is asynchronous.

The async keyword was mainly added to avoid backwards compatibility problems when using the await keyword

An async method can have a return type of Task, Task<TResult>, or void

The await operator is applied to a task in an asynchronous method to suspend the execution of the method until the awaited task completes

Page 25: Training – Going Async

await/async control flow

Control Flow in Async Programs

Page 26: Training – Going Async

Await/await with .net 4.0

• It’s possible to use async/await in projects targeting .net 4.0

• It does not include the ASP.NET runtime changes necessary for proper async/await support, so if you install it into an ASP.NET 4.0 project, the code will compile but will not work correctly

• It’s better to upgade to 4.5

Page 27: Training – Going Async

There is no thread

“if I am awaiting an operation, there must be a thread that is doing the wait! It’s probably a thread pool thread. Or an OS thread! Or something with a device driver…”

There is no thread

“Regardless of the type of I/O request, internally I/O operations issued to a driver

on behalf of the application are performed asynchronously”,

Windows Internals

Page 28: Training – Going Async

Working with TPL

Page 29: Training – Going Async

How do I know which method is async or not ?

The .NET Framework 4.5 contains many members that work with async and await. You can recognize these members by the "Async" suffix that’s attached to the member name and a return type of Task or Task<TResult>.

Library methods shouldn’t lie.Be honest. Use “XxAsync” if, and only if, you’re not thread-bound (with a few notable exceptions).Suffix should help caller to understand implementation.

Page 30: Training – Going Async

TAP Guidelines

There are many new await-friendly techniques that should be used instead of the old blocking techniques. If you have any of these Old examples in your new async code, you’re Doing It Wrong. TAP Guidelines

Page 31: Training – Going Async

Async all the way

• “await and async” is poison. – Await/await isn’t intended to be used in just a single function, but for an entire flow in

your application.

– Once you will add them somewhere in your code. These keywords will propagate all of the way up to the top of a logical stack.

• Asynchronous code works best if asynchronous code calls and is called by other asynchronous code

• Don’t mix synchronous and asynchronous code (without carefully considering the consequences)– bad idea to block on async code by calling Task.Wait or Task.Result.

– Mixed async and blocking code can cause deadlocks, more-complex error handling and unexpected blocking of context threads

• Exceptions– Console Applications, Unit Tests

Page 32: Training – Going Async

Asynchronous wrappers for synchronous methods?“async over sync”

• Two primary benefits to asynchrony: scalability and offloading (e.g. responsiveness, parallelism)

• Scalability– still consuming the same amount of resources (even a bit more)

– Don’t put Task.Run everywhere to achieve async over sync. Use a thread from the thread pool.

• Offloading– if a consumer of your library wants to use the synchronous method asynchronously,

they can do so on their own

http://blogs.msdn.com/b/pfxteam/archive/2012/03/24/10287244.aspx

Async

Page 33: Training – Going Async

Synchronous wrappers for asynchronous methods?“sync over async”

• Avoid exposing a synchronous method that just wraps the asynchronous implementation– hides from the consumer the true nature of the implementation

– If the consumer chooses to block waiting for the asynchronous implementation to complete, that’s up to the caller

• Can lead to significant problems with the application, such as hangs

http://blogs.msdn.com/b/pfxteam/archive/2012/04/13/10293638.aspx

Page 34: Training – Going Async

Async with asp.net (API or MVC)What benefits ?

Introduction to Async/Await on ASP.NET

In the case of I/O bound operations (whether that's disk I/O or network I/O), the waiting that a thread might normally do is purposeless. Using an async version of the I/O method allows the worker thread -- which are generally in limited supply -- to go back into the worker pool to start servicing another request. When the I/O is ready, and a thread from the worker pool is available, then the original request can be completed. This can have a fairly substantial benefit in scalability of the server, because it means servicing lots more requests with far fewer resources.

Don’t forget Parallelization : do not call sequentially N operations but parallelize work, and therefore return the data to the client sooner

Page 35: Training – Going Async

Tasks and asp.net MVC

The way to build asynchronous controllers has been completely changed compared to how it was done previously with the AsyncController superclass. This class and the inherent complexity in using it are gone.

Async

Page 36: Training – Going Async

Task in asp.net Web Api

Mark your Api action with async + Task<Result>

Message handlers also support async/await. (Cleaner than writing it with a continuation task).

Page 37: Training – Going Async

TPL Best Practices

Page 38: Training – Going Async

Async is for “long” tasks

As there is a small overhead of using async (SynchronizationContext, Task Creation, Task Scheduling, Queueing…) ; so Do not put async everwhere. It won’t help.

• Use where .NET 4.5 framework is Async– Network I/O

– File I/O

– Database I/O

• CAUTION! (not all providers are async)

– Remote Service Calls

• Use for CPU-bound work– > 50ms with a user waiting

– For server code, it depends

Page 39: Training – Going Async

Consider using await instead of ContinueWith/Unwrap

• Async/await is better– Easier to read

– Fewer context switches

– Better memory footprint –especially with chained tasks

– Less startup overhead

TPL 4.5 Performance improvements

Page 40: Training – Going Async

Use cached Tasks when possible

“While we have strived to slim down Task and eliminate unnecessary allocations in .NET 4.5, the optimal allocation is one that never happens. Sometimes it is possible to cache a single instance of a frequently used Task, eliminating the need to continually re-allocate the Task.”, Stephen Toub

• Cache the Tasks, not the Data

• reuse completed tasks

• Use completed & static Tasks– Use Task.FromResult

Page 41: Training – Going Async

Encode closure information into a Task’s state object

Compilation

• Pass values by parameter where possible

• Only capture the variable you are going to use.– Use local variables when necessary

Page 42: Training – Going Async

Don’t block on async codeUI Client UI Asp.net

Deadlock ! Why ?

Don’t block on async code

• After you await a Task, when the method continues it will continue in a context.

• GUI and ASP.NET applications have a SynchronizationContext that permits only one chunk of code to run at a time

Page 43: Training – Going Async

Don't block on async code

Call ConfigureAwait

• Don’t Wait on Tasks– Let the runtime schedule the continuations

• Don’t access Task.Result unless it’s completed– Task.Result is blocking

• If you must, be aware of synchronized contexts:– UI Threads

– ASP.NET Threads

• For API developpers– Call ConfigureAwait(false) It’s all about SynchronizationContext

Don’t block on Tasks; use async all the way down

Page 44: Training – Going Async

Use Async void for event Handlers

void is a possible return type (with Task and Task<Result>) for an async method

• Principles– Async void is a “fire-and-forget” mechanism...

– The caller is unable to know when an async void has finished

– The caller is unable to catch exceptions thrown from an async void

• Guidance– Use async void methods only for top-level event handlers (and their like)

– Use async Task-returning methods everywhere else

– When you see an async lambda, verify it

Async void Tips

Page 45: Training – Going Async

TPL Dataflow

• TPL DataFlow is a library for building asynchronous data processing application

• Not distributed with the .NET Framework 4.5, avaible via Nuget

• A natural extension of the TPL library that allows developers to create data-processing pipelines in their applications

• Many concepts of Actor model

TPL Dataflow on MSDN

Page 46: Training – Going Async

Not Async

Not Running Asynchronously. Why ?

‘async’ don’t forks.Use Task.Run to offload

Page 47: Training – Going Async

Method not completing

Awaited task sometimes never completes. Why ?

Always complete Tasks when the underlying operation has ended

Deadlocking UI thread.Why ?

Don’t synchronously wait on the UI thread.Use ConfigureAwait(false) whenever possible.

Page 48: Training – Going Async

Questions

Page 49: Training – Going Async

References

• http://www.codeproject.com/Articles/518856/Task-Parallel-Library-and-async-await-Functionalit

• http://msdn.microsoft.com/en-us/library/dd997423(v=vs.110).aspx

• http://www.asp.net/aspnet/overview/developing-apps-with-windows-azure/building-real-world-cloud-apps-with-windows-azure/web-development-best-practices#sessionstate

• http://blog.stephencleary.com/

• http://msdn.microsoft.com/en-us/magazine/jj991977.aspx

• http://msdn.microsoft.com/fr-fr/magazine/dn802603(en-us).aspx

• http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt1.html

• http://download.microsoft.com/download/5/B/9/5B924336-AA5D-4903-95A0-56C6336E32C9/TAP.docx

• http://blogs.msdn.com/b/dotnet/archive/2012/04/03/async-in-4-5-worth-the-await.aspx

• http://msdn.microsoft.com/en-us/magazine/gg598924.aspx

• http://msdn.microsoft.com/en-us/library/hh191443.aspx

• http://www.codeproject.com/Articles/562021/Asynchronous-models-and-patterns#await-async

• http://www.codeproject.com/Articles/518856/Task-Parallel-Library-and-async-await-Functionalit

• http://blogs.msdn.com/b/pfxteam/archive/2012/04/12/10293335.aspx

• http://msdn.microsoft.com/en-us/library/hh873173.aspx

• http://www.microsoft.com/en-us/download/confirmation.aspx?id=19957

• http://code.jonwagner.com/2012/09/06/best-practices-for-c-asyncawait/