Download presentation
1
TAP into async programming
Chris Dahlberg
2
Platinum Sponsors Silver Sponsors Gold Sponsors
3
Threading Models Single-Threaded Explicit Thread Management
Thread Pool Asynchronous Programming Model (APM) Event-Based Asynchronous Pattern (EAP) Task-Based Asynchronous Pattern (TAP) Async/Await
4
Single-Threaded Simplest Available in all .NET versions
5
Explicit Thread Management
Varying complexity Available in all .NET versions
6
Thread Pool Simple Available in all .NET versions
7
Event-Based Asynchronous Pattern
Not simple Available in .NET 2.0 and newer
8
Asynchronous Programming Model
Not simple Available in .NET 2.0 and newer
9
Task-Based Asynchronous Pattern (TAP)
Simple Available in .NET 4.0 and newer
10
Async/Await Simple Available in .NET 4.5 and newer
11
Why Use Async/Await? Simplicity Single-Threaded: Async/Await:
Can be nearly as simple as single-threaded code Single-Threaded: Async/Await:
12
Why Use Async/Await? (cont’d)
Performance Run IO-bound code asynchronously Avoid blocking GUI threads Use IIS worker threads more efficiently Run CPU-bound code in parallel More efficiently use all available CPU cores
13
WCF Service Performance Example
Server Azure VM, Single CPU Client Laptop with Core i7 CPU 150 requesting threads GetCurrentTimeSlow IIS reached 118 threads 468 requests per second GetCurrentTimeAsync IIS stayed at 20 threads 480 requests per second
14
Parallel Performance Example
Run on a 4-core CPU GetNumber 1.83 seconds GetNumberAsync 0.55 seconds
15
How Async/Await Works If a Task is completed when awaited, await runs synchronously If a Task is not yet completed when awaited: ExecutionContext (including SynchronizationContext) is saved The thread of the calling method can be used to run other code Once the awaited task completes, the method that called await continues executing using the saved ExecutionContext ASP.NET, WPF, etc. each have their own special contexts When SynchronizationContext is null, the calling method continues on the ThreadPool context
16
Basic Things to Know Await can only be used in methods marked with the async modifier Async methods must have a return type of Task, Task<T>, or void For methods that do not return a value, use Task For methods that return a value, use Task<T> Do not use void Async method names should have an “Async” suffix Sync: string GetName() Async: Task<string> GetNameAsync() Tasks returned by async methods should already be started
17
Where to Use Async/Await
Ideally, use async code pervasively “Grows like a virus” from entry point to API If necessary, use async code which… …calls other threading models …is called by other threading models
18
Common Async Entry Points
Event handlers Windows Forms Windows Presentation Foundation Service operations Windows Communication Foundation WebAPI
19
Event Handler Example The only situation where async void methods should be used Event handlers typically do not include an “Async” suffix
20
Service Operation Example
Methods in contracts should include the Async suffix The Async suffix will not be included in WSDL or visible to clients Worker threads can be freed and handle additional requests
21
Common Async APIs Service clients Streams Database clients
Entity Framework Networking clients
22
Async Service Client APIs
Svcutil.exe can generate Async variants of methods
23
Async Stream APIs Stream methods StreamReader methods
ReadAsync(byte[], int, int) WriteAsync(byte[], int, int) StreamReader methods ReadBlockAsync(char[], int, int) ReadLineAsync() ReadToEndAsync() StreamWriter methods WriteAsync(string) WriteLineAsync(string)
24
Async Database APIs DbConnection methods DbCommand methods
OpenAsync() DbCommand methods ExecuteNonQueryAsync() ExecuteReaderAsync() ExecuteScalarAsync() DbDataReader methods ReadAsync() NextResultAsync()
25
Async Entity Framework APIs
DbSet<T> methods FindAsync IQueryable<T> methods AllAsync, AnyAsync AverageAsync, SumAsync ContainsAsync CountAsync, LongCountAsync FirstAsync, FirstOrDefaultAsync MaxAsync, MinAsync SingleAsync, SingleOrDefaultAsync ToArrayAsync, ToDictionaryAsync, ToListAsync
26
Async Networking Client Methods
TcpClient methods ConnectAsync UdpClient methods ReceiveAsync SendAsync
27
Calling Other Threading Models
Event-Based Asynchronous Pattern (EAP) Asynchronous Programming Model (APM)
28
Calling Event-Based Asynchronous Pattern
29
Calling Asynchronous Programming Model
30
Called By Other Threading Models
Event-Based Asynchronous Pattern (EAP) Asynchronous Programming Model (APM) Single-threaded code
31
Called By Event-Based Asynchronous Pattern
32
Called By Asynchronous Programming Model
33
Called By Single-Threaded Code
Don’t do it Ok, if you must do it, use Task.Run var result = Task.Run(() => DoSomethingAsync()).Result;
34
Best Practices Do not create async methods that contain only CPU-bound code Do not use Task.Run to create an async wrapper method around CPU-bound code Do not use async void methods except for event handlers Exceptions thrown from async void method can not be caught in a try/catch block. Tasks do not need to be disposed unless the AsyncWaitHandle property is accessed Always use .ConfigureAwait(false) in library code
35
Pitfalls Deadlocks Exceptions wrapped in AggregateException
Thread synchronization limitations Entity Framework limitations IIS request limits
36
Deadlocks Multiple tasks waiting for the same SynchronizationContext
To avoid, use .ConfigureAwait(false) whenever possible Non-async code waiting on an async Task To avoid, use Task.Run to run async code from non-async code
37
Exceptions Wrapped in AggregateException
When calling .Wait() or .Result, exceptions are wrapped in an AggregateException Can use .GetAwaiter().GetResult(), which will throw the actual exception Can catch AggregateException and manually get the actual exception AggregateException.Flatten().InnerExceptions.First()
38
Thread Synchronization Limitations
await can not be used… …within lock blocks …between Monitor.Enter and Monitor.Exit …between Mutex.WaitOne and Mutex.ReleaseMutex
39
Entity Framework Limitations
Unable to have multiple simultaneous async operations Must use multiple DbContexts
40
IIS Request Limits On most non-server versions of Windows, IIS limits the number of concurrent requests to 10
41
Tips and Tricks Custom thread synchronization Task dependencies
AsyncLazy Caching tasks TaskCompletionSource
42
Custom Thread Synchronization
Could create your own using a combination of lock statements, ConcurrentQueues, Interlocked.CompareExchange, and TaskCompletionSources Could use an AsyncLock implementation that is already available from NuGet Nito.AsyncEx (by Stephen Cleary) 13,987 downloads of the latest version CodeTiger.Core (by me) 55 downloads of the latest version
43
Task Dependencies Pass Task and Task<T> objects into other async methods
44
AsyncLazy Comparable to Lazy<Task<T>>
Lazy<Task<T>: AsyncLazy<T>:
45
Caching Tasks Cache completed tasks to return from Async methods
46
TaskCompletionSource
Provides a Task that does not itself run code Typically not needed when writing pure async code Can be used to interact with other threading models
47
Helpful Blogs Stephen Cleary
Parallel Programming with .NET (Stephen Toub)
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.