SlideShare a Scribd company logo
1 of 24
Async demystified
NDC Sydney 2019
Karel Zikmund – @ziki_cz
Agenda
• History of async patterns in .NET
• History and evolution of
• Task
• async-await
APM pattern:
Asynchronous Programming Model
.NET Framework 1.0/1.1 … 2002-2003
interface IAsyncResult
{
bool IsCompleted;
bool IsCompletedSynchronously;
object AsyncState;
WaitHandle AsyncWaitHandle;
}
Across BCL:
IAsyncResult BeginFoo(..., AsyncCallback callback, object state);
void EndFoo(IAsyncResult iar);
APM pattern
IAsyncResult BeginFoo(..., AsyncCallback callback, object state);
void EndFoo(IAsyncResult iar);
Synchronous call:
Foo();
Achieving the same:
EndFoo(BeginFoo(..., null, null));
Taking advantage of the asynchronous nature:
BeginFoo(..., iar => {
T val = EndFoo(iar);
// do stuff ...
});
APM – Example
Copy stream to stream:
int bytesRead;
while ((bytesRead = input.Read(buffer)) != 0) {
output.Write(buffer, 0 /* offset */, bytesRead);
}
APM – Nesting problem
BeginRead(..., iar => {
int bytesRead = EndRead(iar);
input.BeginWrite(..., iar2 => {
int bytesWritten2 = EndWrite(iar2);
BeginRead(..., iar3 => {
int bytesRead3 = EndRead(iar3);
BeginWrite(..., iar4 => {
// ... again and again
});
});
});
});
APM – IsCompletedSynchronously
IAsyncResult r = BeginRead(..., iar => {
if (!iar.IsCompletedSynchronously) {
// ... asynchronous path as shown earlier
}
});
if (r.IsCompletedSynchronously) {
// ... Synchronous path
}
• Even worse in loop
• Overall very complicated
• Queueing on ThreadPool much simpler
EAP:
Event-based Asynchronous Pattern
• .NET Framework 2.0
obj.Completed += (sender, eventArgs) => {
// ... my event handler
}
obj.SendPacket(); // returns void
• Did not solve multiple-calls problem, or loops
• Introduced ExecutionContext
Task
• .NET Framework 4.0
• MSR project – parallel computing
• Divide & conquer efficiently (e.g. QuickSort)
• Shaped Task – similar to today
• Task – represents general work (compute, I/O bound, etc.)
= promise / future / other terminology
• Task / Task<T> – operation (with optional result T) contains:
1. T … in the case of Task<T>
2. State related to synchronization
3. State related to callback
Task / TaskCompletionSource
• Task
• Here's a callback, invoke it when you're done, or right now if you've already
completed
• I want to block here, until your work is done
• Cannot be completed by user directly
• TaskCompletionSource … wrapper for Task
• Holds Task internally and operates on it via internal methods
• Methods:
• SetResult
• SetException
• SetCancelled
Task – Consumption
Task<T> t;
Either:
t.Wait(); // Blocks until Task is completed
Or:
t.ContinueWith(callback); // Will be executed after Task is completed
Even multiple times:
t.ContinueWith(callback2);
t.ContinueWith(callback3);
ContinueWith:
• Does not guarantee order of executions
• Always asynchronous (queued to ThreadPool/scheduler in general)
Task.Run
We complicated things 
Task<T> Task.Run(delegate d)
• Adds field to Task with ‘d’
• Queues work to ThreadPool
• Thread grabs it, executes it, marks task completed
Task.Run implementation
Task<T> Run(Func<T> f) {
var tcs = new TaskCompletionSource<T>();
ThreadPool.QueueUserWorkItem(() => {
try {
T result = f();
tcs.SetResult(result);
} catch (ex) {
tcs.SetException(ex);
}
});
return tcs.Task;
}
async-await
.NET Framework 4.5 / C# 5
Example of asynchronous code:
Task<int> GetDataAsync();
Task PutDataAsync(int i);
Code:
Task<int> t = GetDataAsync();
t.ContinueWith(a => {
var t2 = PutDataAsync(a.Result);
t2.ContinueWith(b => Console.WriteLine("done"));
});
async-await
Task<int> t = GetDataAsync();
t.ContinueWith(a => {
var t2 = PutDataAsync(a.Result);
t2.ContinueWith(b => Console.WriteLine("done"));
});
C# 5 with async-await helps us:
Task<int> t = GetDataAsync();
int aResult = await t;
Task t2 = PutDataAsync(aResult);
await t2;
Console.WriteLine("done");
Awaiter pattern
int aResult = await t;
Translated to:
var $awaiter1 = t.GetAwaiter();
if (! $awaiter1.IsCompleted) { // returns bool
// ... (complicated) ...
}
int aResult = $awaiter1.GetResult(); // returns void or T
// If exception, it will throw it
Awaiter pattern – details
void MoveNext() {
if (__state == 0) goto label0;
if (__state == 1) goto label1;
if (__state == 42) goto label42;
if (! $awaiter1.IsCompleted) {
__state = 42;
$awaiter1.OnCompleted(MoveNext);
return;
}
label42:
int aResult = $awaiter1.GetResult();
}
State Machine
string x = Console.ReadLine();
int aResult = await t;
Console.WriteLine("done" + x);
State machine:
struct MethodFooStateMachine {
void MoveNext() { ... }
local1; // would be ‘x’ in example above
local2;
params;
_$awaiter1;
__state;
}
State Machine – Example
public async Task Foo(int timeout) {
await Task.Delay(timeout);
}
Compiler generates:
public Task Foo(int timeout) {
FooStateMachine sm = default;
sm._timeout = timeout;
sm._state = 0;
sm.MoveNext();
return ???;
}
struct FooStateMachine {
int _timeout; // param
// locals would be here too
void MoveNext() { ... }
int __state;
TaskAwaiter _$awaiter1;
}
State Machine – Example
public Task Foo(int timeout) {
FooStateMachine sm = default;
sm._tcs = new TaskCompletionSource();
sm._timeout = timeout;
sm._state = 0;
sm.MoveNext();
return sm._tcs.Task;
}
Builder pattern (can return struct):
AsyncValueTaskMethodBuilder.Create();
_tcs.Task -> _builder.Task;
struct FooStateMachine {
int _timeout; // param
// locals would be here too
void MoveNext() {
// ...
_tcs.SetResult(...);
}
int _state;
TaskAwaiter _$awaiter1;
TaskCompletionSource _tcs;
}
State Machine – Perf improvements
What about Task allocation?
• Builder can reuse known tasks
• Task.CompletedTask (without value)
• boolean – True/False
• int … <-1,8>
• LastCompleted (e.g. on MemoryStream)
• Does not work on SslStream (alternates headers and body)
• Size: 64B (no value) / 72B (with value)
• Azure workloads OK (GC will collect)
• Hot-path: up to 5%-10% via more GCs
ValueTask
• .NET Core 2.0
• Also as nuget package down-level
struct ValueTask<T> {
T;
Task<T>;
}
• Only one of them: T+null or default+Task<T>
• NET Core 2.1
ValueTask<int> Stream.ReadAsync(Memory<byte>, ...)
ValueTask – Can we improve more?
• What about the 1% asynchronous case?
• .NET Core 2.1
struct ValueTask<T> {
T;
Task<T>;
IValueTaskSource<T>;
}
struct ValueTask {
Task;
IValueTaskSource;
}
Summary
• APM pattern = Asynchronous Programming Model
• .NET Framework 1.0/1.1 (2002-2003)
• IAsyncResult, BeginFoo/EndFoo
• Limited nesting / loops
• EAP = Event-based Asynchronous Pattern (.NET Framework 2.0)
• Events – similar problems as APM
• Task (.NET Framework 4.0)
• Wait / ContinueWith
• TaskCompletionSource (for control/writing)
• async-await (.NET Framework 4.5 / C# 5)
• Awaiter pattern, state machine
• ValueTask (.NET Core 2.0)
• Don’t use unless you are on hot-path
• Hyper-optimizations possible, stay away, it is dangerous! 
@ziki_cz

More Related Content

Similar to Async demystified: A history of async patterns in .NET

C#을 이용한 task 병렬화와 비동기 패턴
C#을 이용한 task 병렬화와 비동기 패턴C#을 이용한 task 병렬화와 비동기 패턴
C#을 이용한 task 병렬화와 비동기 패턴명신 김
 
Grand Central Dispatch in Objective-C
Grand Central Dispatch in Objective-CGrand Central Dispatch in Objective-C
Grand Central Dispatch in Objective-CPavel Albitsky
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...corehard_by
 
Advanced patterns in asynchronous programming
Advanced patterns in asynchronous programmingAdvanced patterns in asynchronous programming
Advanced patterns in asynchronous programmingMichael Arenzon
 
Async and parallel patterns and application design - TechDays2013 NL
Async and parallel patterns and application design - TechDays2013 NLAsync and parallel patterns and application design - TechDays2013 NL
Async and parallel patterns and application design - TechDays2013 NLArie Leeuwesteijn
 
Asynchronní programování
Asynchronní programováníAsynchronní programování
Asynchronní programováníPeckaDesign.cz
 
Binary Studio Academy: Concurrency in C# 5.0
Binary Studio Academy: Concurrency in C# 5.0Binary Studio Academy: Concurrency in C# 5.0
Binary Studio Academy: Concurrency in C# 5.0Binary Studio
 
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
 
Kotlin - Coroutine
Kotlin - CoroutineKotlin - Coroutine
Kotlin - CoroutineSean Tsai
 
Coroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth reviewCoroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth reviewDmytro Zaitsev
 
Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.UA Mobile
 
.NET Multithreading and File I/O
.NET Multithreading and File I/O.NET Multithreading and File I/O
.NET Multithreading and File I/OJussi Pohjolainen
 
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...DroidConTLV
 
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docxIn Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docxbradburgess22840
 
Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsPiotr Pelczar
 
Programming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdf
Programming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdfProgramming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdf
Programming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdfssuser6254411
 

Similar to Async demystified: A history of async patterns in .NET (20)

C#을 이용한 task 병렬화와 비동기 패턴
C#을 이용한 task 병렬화와 비동기 패턴C#을 이용한 task 병렬화와 비동기 패턴
C#을 이용한 task 병렬화와 비동기 패턴
 
Grand Central Dispatch in Objective-C
Grand Central Dispatch in Objective-CGrand Central Dispatch in Objective-C
Grand Central Dispatch in Objective-C
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
 
C++ Functions
C++ FunctionsC++ Functions
C++ Functions
 
Appsec obfuscator reloaded
Appsec obfuscator reloadedAppsec obfuscator reloaded
Appsec obfuscator reloaded
 
Advanced patterns in asynchronous programming
Advanced patterns in asynchronous programmingAdvanced patterns in asynchronous programming
Advanced patterns in asynchronous programming
 
Async and parallel patterns and application design - TechDays2013 NL
Async and parallel patterns and application design - TechDays2013 NLAsync and parallel patterns and application design - TechDays2013 NL
Async and parallel patterns and application design - TechDays2013 NL
 
Asynchronní programování
Asynchronní programováníAsynchronní programování
Asynchronní programování
 
Binary Studio Academy: Concurrency in C# 5.0
Binary Studio Academy: Concurrency in C# 5.0Binary Studio Academy: Concurrency in C# 5.0
Binary Studio Academy: Concurrency in C# 5.0
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJS
 
Using zone.js
Using zone.jsUsing zone.js
Using zone.js
 
Kotlin - Coroutine
Kotlin - CoroutineKotlin - Coroutine
Kotlin - Coroutine
 
Coroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth reviewCoroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth review
 
Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.
 
.NET Multithreading and File I/O
.NET Multithreading and File I/O.NET Multithreading and File I/O
.NET Multithreading and File I/O
 
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
 
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docxIn Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
 
Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.js
 
Java 8
Java 8Java 8
Java 8
 
Programming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdf
Programming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdfProgramming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdf
Programming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdf
 

More from Karel Zikmund

.NET Conf 2022 - Networking in .NET 7
.NET Conf 2022 - Networking in .NET 7.NET Conf 2022 - Networking in .NET 7
.NET Conf 2022 - Networking in .NET 7Karel Zikmund
 
NDC London 2020 - Challenges of Managing CoreFx Repo -- Karel Zikmund
NDC London 2020 - Challenges of Managing CoreFx Repo -- Karel ZikmundNDC London 2020 - Challenges of Managing CoreFx Repo -- Karel Zikmund
NDC London 2020 - Challenges of Managing CoreFx Repo -- Karel ZikmundKarel Zikmund
 
WUG Days 2022 Brno - Networking in .NET 7.0 and YARP -- Karel Zikmund
WUG Days 2022 Brno - Networking in .NET 7.0 and YARP -- Karel ZikmundWUG Days 2022 Brno - Networking in .NET 7.0 and YARP -- Karel Zikmund
WUG Days 2022 Brno - Networking in .NET 7.0 and YARP -- Karel ZikmundKarel Zikmund
 
.NET Core Summer event 2019 in Vienna, AT - .NET 5 - Future of .NET on Mobile...
.NET Core Summer event 2019 in Vienna, AT - .NET 5 - Future of .NET on Mobile....NET Core Summer event 2019 in Vienna, AT - .NET 5 - Future of .NET on Mobile...
.NET Core Summer event 2019 in Vienna, AT - .NET 5 - Future of .NET on Mobile...Karel Zikmund
 
.NET Core Summer event 2019 in Linz, AT - War stories from .NET team -- Karel...
.NET Core Summer event 2019 in Linz, AT - War stories from .NET team -- Karel....NET Core Summer event 2019 in Linz, AT - War stories from .NET team -- Karel...
.NET Core Summer event 2019 in Linz, AT - War stories from .NET team -- Karel...Karel Zikmund
 
.NET Core Summer event 2019 in Brno, CZ - .NET Core Networking stack and perf...
.NET Core Summer event 2019 in Brno, CZ - .NET Core Networking stack and perf....NET Core Summer event 2019 in Brno, CZ - .NET Core Networking stack and perf...
.NET Core Summer event 2019 in Brno, CZ - .NET Core Networking stack and perf...Karel Zikmund
 
.NET Core Summer event 2019 in Brno, CZ - War stories from .NET team -- Karel...
.NET Core Summer event 2019 in Brno, CZ - War stories from .NET team -- Karel....NET Core Summer event 2019 in Brno, CZ - War stories from .NET team -- Karel...
.NET Core Summer event 2019 in Brno, CZ - War stories from .NET team -- Karel...Karel Zikmund
 
.NET Core Summer event 2019 in Prague, CZ - War stories from .NET team -- Kar...
.NET Core Summer event 2019 in Prague, CZ - War stories from .NET team -- Kar....NET Core Summer event 2019 in Prague, CZ - War stories from .NET team -- Kar...
.NET Core Summer event 2019 in Prague, CZ - War stories from .NET team -- Kar...Karel Zikmund
 
.NET Core Summer event 2019 in Vienna, AT - War stories from .NET team -- Kar...
.NET Core Summer event 2019 in Vienna, AT - War stories from .NET team -- Kar....NET Core Summer event 2019 in Vienna, AT - War stories from .NET team -- Kar...
.NET Core Summer event 2019 in Vienna, AT - War stories from .NET team -- Kar...Karel Zikmund
 
.NET Core Summer event 2019 in NL - War stories from .NET team -- Karel Zikmund
.NET Core Summer event 2019 in NL - War stories from .NET team -- Karel Zikmund.NET Core Summer event 2019 in NL - War stories from .NET team -- Karel Zikmund
.NET Core Summer event 2019 in NL - War stories from .NET team -- Karel ZikmundKarel Zikmund
 
NDC Oslo 2019 - War stories from .NET team -- Karel Zikmund
NDC Oslo 2019 - War stories from .NET team -- Karel ZikmundNDC Oslo 2019 - War stories from .NET team -- Karel Zikmund
NDC Oslo 2019 - War stories from .NET team -- Karel ZikmundKarel Zikmund
 
DotNext 2017 in Moscow - Challenges of Managing CoreFX repo -- Karel Zikmund
DotNext 2017 in Moscow - Challenges of Managing CoreFX repo -- Karel ZikmundDotNext 2017 in Moscow - Challenges of Managing CoreFX repo -- Karel Zikmund
DotNext 2017 in Moscow - Challenges of Managing CoreFX repo -- Karel ZikmundKarel Zikmund
 
DotNext 2017 in Moscow - .NET Core Networking stack and Performance -- Karel ...
DotNext 2017 in Moscow - .NET Core Networking stack and Performance -- Karel ...DotNext 2017 in Moscow - .NET Core Networking stack and Performance -- Karel ...
DotNext 2017 in Moscow - .NET Core Networking stack and Performance -- Karel ...Karel Zikmund
 
.NET MeetUp Brno 2017 - Microsoft Engineering teams in Europe -- Karel Zikmund
.NET MeetUp Brno 2017 - Microsoft Engineering teams in Europe -- Karel Zikmund.NET MeetUp Brno 2017 - Microsoft Engineering teams in Europe -- Karel Zikmund
.NET MeetUp Brno 2017 - Microsoft Engineering teams in Europe -- Karel ZikmundKarel Zikmund
 
.NET MeetUp Brno 2017 - Xamarin .NET internals -- Marek Safar
.NET MeetUp Brno 2017 - Xamarin .NET internals -- Marek Safar.NET MeetUp Brno 2017 - Xamarin .NET internals -- Marek Safar
.NET MeetUp Brno 2017 - Xamarin .NET internals -- Marek SafarKarel Zikmund
 
.NET MeetUp Brno - Challenges of Managing CoreFX repo -- Karel Zikmund
.NET MeetUp Brno - Challenges of Managing CoreFX repo -- Karel Zikmund.NET MeetUp Brno - Challenges of Managing CoreFX repo -- Karel Zikmund
.NET MeetUp Brno - Challenges of Managing CoreFX repo -- Karel ZikmundKarel Zikmund
 
.NET Fringe 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund
.NET Fringe 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund.NET Fringe 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund
.NET Fringe 2017 - Challenges of Managing CoreFX repo -- Karel ZikmundKarel Zikmund
 
.NET MeetUp Prague 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund
.NET MeetUp Prague 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund.NET MeetUp Prague 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund
.NET MeetUp Prague 2017 - Challenges of Managing CoreFX repo -- Karel ZikmundKarel Zikmund
 
.NET MeetUp Prague 2017 - .NET Standard -- Karel Zikmund
.NET MeetUp Prague 2017 - .NET Standard -- Karel Zikmund.NET MeetUp Prague 2017 - .NET Standard -- Karel Zikmund
.NET MeetUp Prague 2017 - .NET Standard -- Karel ZikmundKarel Zikmund
 
.NET MeetUp Amsterdam 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund
.NET MeetUp Amsterdam 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund.NET MeetUp Amsterdam 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund
.NET MeetUp Amsterdam 2017 - Challenges of Managing CoreFX repo -- Karel ZikmundKarel Zikmund
 

More from Karel Zikmund (20)

.NET Conf 2022 - Networking in .NET 7
.NET Conf 2022 - Networking in .NET 7.NET Conf 2022 - Networking in .NET 7
.NET Conf 2022 - Networking in .NET 7
 
NDC London 2020 - Challenges of Managing CoreFx Repo -- Karel Zikmund
NDC London 2020 - Challenges of Managing CoreFx Repo -- Karel ZikmundNDC London 2020 - Challenges of Managing CoreFx Repo -- Karel Zikmund
NDC London 2020 - Challenges of Managing CoreFx Repo -- Karel Zikmund
 
WUG Days 2022 Brno - Networking in .NET 7.0 and YARP -- Karel Zikmund
WUG Days 2022 Brno - Networking in .NET 7.0 and YARP -- Karel ZikmundWUG Days 2022 Brno - Networking in .NET 7.0 and YARP -- Karel Zikmund
WUG Days 2022 Brno - Networking in .NET 7.0 and YARP -- Karel Zikmund
 
.NET Core Summer event 2019 in Vienna, AT - .NET 5 - Future of .NET on Mobile...
.NET Core Summer event 2019 in Vienna, AT - .NET 5 - Future of .NET on Mobile....NET Core Summer event 2019 in Vienna, AT - .NET 5 - Future of .NET on Mobile...
.NET Core Summer event 2019 in Vienna, AT - .NET 5 - Future of .NET on Mobile...
 
.NET Core Summer event 2019 in Linz, AT - War stories from .NET team -- Karel...
.NET Core Summer event 2019 in Linz, AT - War stories from .NET team -- Karel....NET Core Summer event 2019 in Linz, AT - War stories from .NET team -- Karel...
.NET Core Summer event 2019 in Linz, AT - War stories from .NET team -- Karel...
 
.NET Core Summer event 2019 in Brno, CZ - .NET Core Networking stack and perf...
.NET Core Summer event 2019 in Brno, CZ - .NET Core Networking stack and perf....NET Core Summer event 2019 in Brno, CZ - .NET Core Networking stack and perf...
.NET Core Summer event 2019 in Brno, CZ - .NET Core Networking stack and perf...
 
.NET Core Summer event 2019 in Brno, CZ - War stories from .NET team -- Karel...
.NET Core Summer event 2019 in Brno, CZ - War stories from .NET team -- Karel....NET Core Summer event 2019 in Brno, CZ - War stories from .NET team -- Karel...
.NET Core Summer event 2019 in Brno, CZ - War stories from .NET team -- Karel...
 
.NET Core Summer event 2019 in Prague, CZ - War stories from .NET team -- Kar...
.NET Core Summer event 2019 in Prague, CZ - War stories from .NET team -- Kar....NET Core Summer event 2019 in Prague, CZ - War stories from .NET team -- Kar...
.NET Core Summer event 2019 in Prague, CZ - War stories from .NET team -- Kar...
 
.NET Core Summer event 2019 in Vienna, AT - War stories from .NET team -- Kar...
.NET Core Summer event 2019 in Vienna, AT - War stories from .NET team -- Kar....NET Core Summer event 2019 in Vienna, AT - War stories from .NET team -- Kar...
.NET Core Summer event 2019 in Vienna, AT - War stories from .NET team -- Kar...
 
.NET Core Summer event 2019 in NL - War stories from .NET team -- Karel Zikmund
.NET Core Summer event 2019 in NL - War stories from .NET team -- Karel Zikmund.NET Core Summer event 2019 in NL - War stories from .NET team -- Karel Zikmund
.NET Core Summer event 2019 in NL - War stories from .NET team -- Karel Zikmund
 
NDC Oslo 2019 - War stories from .NET team -- Karel Zikmund
NDC Oslo 2019 - War stories from .NET team -- Karel ZikmundNDC Oslo 2019 - War stories from .NET team -- Karel Zikmund
NDC Oslo 2019 - War stories from .NET team -- Karel Zikmund
 
DotNext 2017 in Moscow - Challenges of Managing CoreFX repo -- Karel Zikmund
DotNext 2017 in Moscow - Challenges of Managing CoreFX repo -- Karel ZikmundDotNext 2017 in Moscow - Challenges of Managing CoreFX repo -- Karel Zikmund
DotNext 2017 in Moscow - Challenges of Managing CoreFX repo -- Karel Zikmund
 
DotNext 2017 in Moscow - .NET Core Networking stack and Performance -- Karel ...
DotNext 2017 in Moscow - .NET Core Networking stack and Performance -- Karel ...DotNext 2017 in Moscow - .NET Core Networking stack and Performance -- Karel ...
DotNext 2017 in Moscow - .NET Core Networking stack and Performance -- Karel ...
 
.NET MeetUp Brno 2017 - Microsoft Engineering teams in Europe -- Karel Zikmund
.NET MeetUp Brno 2017 - Microsoft Engineering teams in Europe -- Karel Zikmund.NET MeetUp Brno 2017 - Microsoft Engineering teams in Europe -- Karel Zikmund
.NET MeetUp Brno 2017 - Microsoft Engineering teams in Europe -- Karel Zikmund
 
.NET MeetUp Brno 2017 - Xamarin .NET internals -- Marek Safar
.NET MeetUp Brno 2017 - Xamarin .NET internals -- Marek Safar.NET MeetUp Brno 2017 - Xamarin .NET internals -- Marek Safar
.NET MeetUp Brno 2017 - Xamarin .NET internals -- Marek Safar
 
.NET MeetUp Brno - Challenges of Managing CoreFX repo -- Karel Zikmund
.NET MeetUp Brno - Challenges of Managing CoreFX repo -- Karel Zikmund.NET MeetUp Brno - Challenges of Managing CoreFX repo -- Karel Zikmund
.NET MeetUp Brno - Challenges of Managing CoreFX repo -- Karel Zikmund
 
.NET Fringe 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund
.NET Fringe 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund.NET Fringe 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund
.NET Fringe 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund
 
.NET MeetUp Prague 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund
.NET MeetUp Prague 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund.NET MeetUp Prague 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund
.NET MeetUp Prague 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund
 
.NET MeetUp Prague 2017 - .NET Standard -- Karel Zikmund
.NET MeetUp Prague 2017 - .NET Standard -- Karel Zikmund.NET MeetUp Prague 2017 - .NET Standard -- Karel Zikmund
.NET MeetUp Prague 2017 - .NET Standard -- Karel Zikmund
 
.NET MeetUp Amsterdam 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund
.NET MeetUp Amsterdam 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund.NET MeetUp Amsterdam 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund
.NET MeetUp Amsterdam 2017 - Challenges of Managing CoreFX repo -- Karel Zikmund
 

Recently uploaded

Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)jennyeacort
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 

Recently uploaded (20)

Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 

Async demystified: A history of async patterns in .NET

  • 1. Async demystified NDC Sydney 2019 Karel Zikmund – @ziki_cz
  • 2. Agenda • History of async patterns in .NET • History and evolution of • Task • async-await
  • 3. APM pattern: Asynchronous Programming Model .NET Framework 1.0/1.1 … 2002-2003 interface IAsyncResult { bool IsCompleted; bool IsCompletedSynchronously; object AsyncState; WaitHandle AsyncWaitHandle; } Across BCL: IAsyncResult BeginFoo(..., AsyncCallback callback, object state); void EndFoo(IAsyncResult iar);
  • 4. APM pattern IAsyncResult BeginFoo(..., AsyncCallback callback, object state); void EndFoo(IAsyncResult iar); Synchronous call: Foo(); Achieving the same: EndFoo(BeginFoo(..., null, null)); Taking advantage of the asynchronous nature: BeginFoo(..., iar => { T val = EndFoo(iar); // do stuff ... });
  • 5. APM – Example Copy stream to stream: int bytesRead; while ((bytesRead = input.Read(buffer)) != 0) { output.Write(buffer, 0 /* offset */, bytesRead); }
  • 6. APM – Nesting problem BeginRead(..., iar => { int bytesRead = EndRead(iar); input.BeginWrite(..., iar2 => { int bytesWritten2 = EndWrite(iar2); BeginRead(..., iar3 => { int bytesRead3 = EndRead(iar3); BeginWrite(..., iar4 => { // ... again and again }); }); }); });
  • 7. APM – IsCompletedSynchronously IAsyncResult r = BeginRead(..., iar => { if (!iar.IsCompletedSynchronously) { // ... asynchronous path as shown earlier } }); if (r.IsCompletedSynchronously) { // ... Synchronous path } • Even worse in loop • Overall very complicated • Queueing on ThreadPool much simpler
  • 8. EAP: Event-based Asynchronous Pattern • .NET Framework 2.0 obj.Completed += (sender, eventArgs) => { // ... my event handler } obj.SendPacket(); // returns void • Did not solve multiple-calls problem, or loops • Introduced ExecutionContext
  • 9. Task • .NET Framework 4.0 • MSR project – parallel computing • Divide & conquer efficiently (e.g. QuickSort) • Shaped Task – similar to today • Task – represents general work (compute, I/O bound, etc.) = promise / future / other terminology • Task / Task<T> – operation (with optional result T) contains: 1. T … in the case of Task<T> 2. State related to synchronization 3. State related to callback
  • 10. Task / TaskCompletionSource • Task • Here's a callback, invoke it when you're done, or right now if you've already completed • I want to block here, until your work is done • Cannot be completed by user directly • TaskCompletionSource … wrapper for Task • Holds Task internally and operates on it via internal methods • Methods: • SetResult • SetException • SetCancelled
  • 11. Task – Consumption Task<T> t; Either: t.Wait(); // Blocks until Task is completed Or: t.ContinueWith(callback); // Will be executed after Task is completed Even multiple times: t.ContinueWith(callback2); t.ContinueWith(callback3); ContinueWith: • Does not guarantee order of executions • Always asynchronous (queued to ThreadPool/scheduler in general)
  • 12. Task.Run We complicated things  Task<T> Task.Run(delegate d) • Adds field to Task with ‘d’ • Queues work to ThreadPool • Thread grabs it, executes it, marks task completed
  • 13. Task.Run implementation Task<T> Run(Func<T> f) { var tcs = new TaskCompletionSource<T>(); ThreadPool.QueueUserWorkItem(() => { try { T result = f(); tcs.SetResult(result); } catch (ex) { tcs.SetException(ex); } }); return tcs.Task; }
  • 14. async-await .NET Framework 4.5 / C# 5 Example of asynchronous code: Task<int> GetDataAsync(); Task PutDataAsync(int i); Code: Task<int> t = GetDataAsync(); t.ContinueWith(a => { var t2 = PutDataAsync(a.Result); t2.ContinueWith(b => Console.WriteLine("done")); });
  • 15. async-await Task<int> t = GetDataAsync(); t.ContinueWith(a => { var t2 = PutDataAsync(a.Result); t2.ContinueWith(b => Console.WriteLine("done")); }); C# 5 with async-await helps us: Task<int> t = GetDataAsync(); int aResult = await t; Task t2 = PutDataAsync(aResult); await t2; Console.WriteLine("done");
  • 16. Awaiter pattern int aResult = await t; Translated to: var $awaiter1 = t.GetAwaiter(); if (! $awaiter1.IsCompleted) { // returns bool // ... (complicated) ... } int aResult = $awaiter1.GetResult(); // returns void or T // If exception, it will throw it
  • 17. Awaiter pattern – details void MoveNext() { if (__state == 0) goto label0; if (__state == 1) goto label1; if (__state == 42) goto label42; if (! $awaiter1.IsCompleted) { __state = 42; $awaiter1.OnCompleted(MoveNext); return; } label42: int aResult = $awaiter1.GetResult(); }
  • 18. State Machine string x = Console.ReadLine(); int aResult = await t; Console.WriteLine("done" + x); State machine: struct MethodFooStateMachine { void MoveNext() { ... } local1; // would be ‘x’ in example above local2; params; _$awaiter1; __state; }
  • 19. State Machine – Example public async Task Foo(int timeout) { await Task.Delay(timeout); } Compiler generates: public Task Foo(int timeout) { FooStateMachine sm = default; sm._timeout = timeout; sm._state = 0; sm.MoveNext(); return ???; } struct FooStateMachine { int _timeout; // param // locals would be here too void MoveNext() { ... } int __state; TaskAwaiter _$awaiter1; }
  • 20. State Machine – Example public Task Foo(int timeout) { FooStateMachine sm = default; sm._tcs = new TaskCompletionSource(); sm._timeout = timeout; sm._state = 0; sm.MoveNext(); return sm._tcs.Task; } Builder pattern (can return struct): AsyncValueTaskMethodBuilder.Create(); _tcs.Task -> _builder.Task; struct FooStateMachine { int _timeout; // param // locals would be here too void MoveNext() { // ... _tcs.SetResult(...); } int _state; TaskAwaiter _$awaiter1; TaskCompletionSource _tcs; }
  • 21. State Machine – Perf improvements What about Task allocation? • Builder can reuse known tasks • Task.CompletedTask (without value) • boolean – True/False • int … <-1,8> • LastCompleted (e.g. on MemoryStream) • Does not work on SslStream (alternates headers and body) • Size: 64B (no value) / 72B (with value) • Azure workloads OK (GC will collect) • Hot-path: up to 5%-10% via more GCs
  • 22. ValueTask • .NET Core 2.0 • Also as nuget package down-level struct ValueTask<T> { T; Task<T>; } • Only one of them: T+null or default+Task<T> • NET Core 2.1 ValueTask<int> Stream.ReadAsync(Memory<byte>, ...)
  • 23. ValueTask – Can we improve more? • What about the 1% asynchronous case? • .NET Core 2.1 struct ValueTask<T> { T; Task<T>; IValueTaskSource<T>; } struct ValueTask { Task; IValueTaskSource; }
  • 24. Summary • APM pattern = Asynchronous Programming Model • .NET Framework 1.0/1.1 (2002-2003) • IAsyncResult, BeginFoo/EndFoo • Limited nesting / loops • EAP = Event-based Asynchronous Pattern (.NET Framework 2.0) • Events – similar problems as APM • Task (.NET Framework 4.0) • Wait / ContinueWith • TaskCompletionSource (for control/writing) • async-await (.NET Framework 4.5 / C# 5) • Awaiter pattern, state machine • ValueTask (.NET Core 2.0) • Don’t use unless you are on hot-path • Hyper-optimizations possible, stay away, it is dangerous!  @ziki_cz

Editor's Notes

  1. Internal talk Warning: Some people find the 1st part as a bit boring recap, some like it
  2. IAsyncResult AsyncWaitHandle – ManualResetEvent or AutoResetEvent Across BCL Usage of the APIs either: Wait for callback to be called, or Call EndFoo which will block until completed
  3. END: Single operation works fine, but in reality you do more – e.g. in a loop
  4. E.g. Network to disk
  5. END: Manually it does not work – somehow turn it into loop It’s possible but extremely long and tricky Further complications with IsCompletedSynchronously (as perf optimization)… next slide
  6. For perf reasons – handle synchronous completions right away At the end: Imagine you did the loop with this as before … on MemoryStream, the data is already available -> instead of ThreadPool, call delegate immediately -> Leads to recursive calls -> ~10K StackOverflow Bottom part: Even BCL has lots of wrappers (e.g. in Networking: LazyAsyncResult) with lots of specializations Very complicated
  7. Straightforward idea – Completed event Kick off operation, then Completed handler is invoked (generally on ThreadPool) END: ExecutionContext – basically a ThreadLocal, which survived until much later and until today in some form BCL: Used in 5-10 classes in BCL … like SmtpMail, TcpClient, BackgroundWorker Downsides: We shipped it in .NET Framework 2.0 and quickly realized that it is interesting experiment, but not exactly addressing real needs
  8. #2 -- “MSR Project” 90% right, 10% keeps Toub awake at night even after 10 years and would love to change it #3 – “Task” NOT tied to ThreadPool – not tied to executing delegate Shove result into it Can be completed Can wake up someone waiting on it
  9. #1 – Task Task – something to consume - hook up to #1.3 – Cannot be completed - not to change directly (no control) #2: TaskCompletionSource – can alter state of Task … has control over Task Example: Lazy initialization (something over network) … you are in charge who can change “work completed” You don’t want others to decide when it is done
  10. Wait - creates ManualResetEvent which will be signaled when one of the SetResult/SetException/SetCancelled is called END: Option: TaskExecutionOption to do it synchronously APM (IAsyncResult) … no shared implementation, everyone had to have their own implementation Task model - you don't pass delegate at creation, but you can walk up on any of them and say "call me when you're done" Enabled abstractions – like async-await await hooks up the callback … we will look into it later
  11. Convenient method – but mixes up things ties it to ThreadPool (breaks abstraction) adds delegate to Task END: Sets completed = execute callback, waking up things waiting on it, etc.
  12. #1 – TaskCompletionSource creates Task #3 – return - returns Task to be awaited on, etc. Now we implemented Task.Run without storing any delegate on Task
  13. #2 - GetData/PutData … maybe across the network
  14. END: Compiler translates it to the code above (hand-waving involved) Note: Compiler does not treat Task specially, but it just looks for pattern (awaiter pattern)
  15. #3 – GetResult Bold methods are pattern matching #4 – complicated comment Simplified version, things are in fact more complicated “! IsCompleted” part is complicated – I have to hook up code that comes back here when task completes
  16. #0 – Let’s look deeper into the “! IsCompleted” #1 – All of it is part of MoveNext method -- it is a state machine, every await in method is state in state machine (hand waving a bit) END: OnCompleted has slightly more complicated signature
  17. #1 – code How does ‘x’ survive? (it is just on stack) – need to capture it Same in lambda – C# compiler lifts local to keep it on heap allocated object (floats through closures) Same in state machine END: Compiler optimizes – stores here things only crossing await boundary Note that in debug -- struct is class -- for debuggability, but for perf struct Why struct? These async methods often complete synchronously – example: BufferedStream … large buffer behind with inner stream If I ask for 1B, but it reads 10K in bulk, then lots of calls finish synchronously If it was class, then we would allocate per call
  18. END: We will talk about return ??? (a Task) in more details on next slide Let’s expand the generated code a bit – Foo and FooStateMachine
  19. #1 – _tcs _tcs (producers) is logically on state machine (a bit more complicated) … reminder: it has Task inside #2 – new TaskCompletionSource Allocated per call / operation Problem #1: 2 allocations – TaskCompletionSource and Task (inside) For the synchronous case we want 0 allocations ideally (BufferedStream example) Problem #2: Even the Task/TaskCompletionSource is problematic, because it is anything Task-like (compiler does not want to hardcore Task) … builder pattern instead of constructor new TSC() Each Task-like type (except Task) has attribute defining builder - builder pattern ValueTask (details later) has one -> AsyncValueTaskMethodBuilder instead of new TaskCompletionSource() -> AsyncValueTaskMethodBuilder.Create(); We have internally in System.Runtime.CompilerServices structs: AsyncTaskMethodBuilder, AsyncTaskMethodBuilder<T>, AsyncVoidMethodBuilder #5 -- Task instead of _tcs.Task -> _builder.Task We eliminated TaskCompletionSource allocation – builder can return struct (ValueTask) END: What about the Task?
  20. CompletedTask – void return value – just info it finished vs. not END: How can we improve the perf even more?
  21. #2 “Only one of them” Methods are 1-liners (if Task<T> == null, do something, else something else) Nicely handles synchronously completing case Note: Non-generic ValueTask does not make sense - only Task inside … we have CompletedTask Problem: Overloading on return type #3 – .NET Core 2.1 Luckily we introduced Memory<T> at the same time, as we cannot overload on return type That's why sometimes in PRs we wrap byte[] in Memory first … to use the ValueTask Design-guidelines: Start with Task … use ValueTask only in hot-path scenarios
  22. IValueTaskSource – complicated interface almost the awaiter pattern: Are you completed? Hook up a call back Get a result All implementations on ValueTask are now ternary Value: You can implement it however you want, incl. reset (reuse) Complicated to do, so not everywhere Socket.SendAsync/ReceiveAsync Object per send/receive … but one at a time (typical) 0 allocation for loop around Send/Receive on Socket Same: NetworkStream, Pipelines, Channels