How C# Async/Await Works (The Classic Way)
ูู
ุง ุจุชูุฌู ุชูุชุจ ููุฏ C# ุทุจูุนู ูุชุณุชุฎุฏู
ููู async ู awaitุ ุงูููุฏ ุจูุธูุฑ ุจุณูุท ูุณูู ุงูู ุชูุฑุฃู. ุฎูููุง ูุจุต ุนูู ุงูู
ุซุงู ุฏู:
ูุฏุง ุงููู ุจูุณู ูู Asynchronous Programming ูู ุง ุจูุณุชุฎุฏู ุงูููู ุชูู ุฏูู
public async Task<int> GetData()
{
// Wait for 1 second
await Task.Delay(1000);
return 5;
}ุงูููุฏ ุฏู ูู ุงูุญูููุฉ ู ุด ุจูุชููุฐ ุจุงูุดูู ุงูุจุณูุท ุงููู ุงูุช ุดุงููู ูุฏุงู ู ุฏู. ุงูู C# compiler ุจูุญูู ุงูููุฏ ุฏู ูุญุงุฌุฉ ุฃุนูุฏ ุจูุชูุฑ ุงุณู ูุง State Machine.
ุชูุฑูุจูุงุ ุงูู compiler ุจูุงุฎุฏ ุงูู ูุซูุฏ ุจุชุงุนุชู ูุจูุญูููุง ูููุงุณ ุฃู Struct ู ุฎููุฉ ูุฑูุจุฉ ู ู ุงูููุฏ ุฏู:
class GetDataStateMachine : IAsyncStateMachine
{
int state;
AsyncTaskMethodBuilder<int> builder;
public void MoveNext()
{
if(state == 0)
{
var task = Task.Delay(1000);
state = 1;
// Register what to do when the task is done
task.GetAwaiter().OnCompleted(MoveNext);
return;
}
// Return the final result
builder.SetResult(5);
}
}ุงููู ุจูุญุตู ููุง ุฅู ุงูู compiler ุจูุฎูู ู ู ุงูุนุฏู :
- ููุงุณ ุฃู Struct ุฌุฏูุฏุฉ ุชู ุงู ูุง.
- ู ูุทู State Machine ูุงู ู.
- ุงูู Builder ุงููู ุจูุจูู ููุฏูุฑ ุงูู
Task. - ุงูู Awaiter ุงููู ุจูุณุชูู ุงููุชูุฌุฉ.
ูู ุฏู ุนุจุงุฑุฉ ุนู Generated Code ุจูุชุนู ู ู ู ูุฑุงู ุนุดุงู ุงูู async ูุดุชุบู.
The Problems with the Classic Approach
ุงูุทุฑููุฉ ุฏู ุดุบุงูุฉ ูููุณ ุฌุฏูุง ูู ุณุชูุฑุฉ ู ู ุฃูุงู C# 5ุ ููู ู ุน ุงูุชุทูุฑุ ุธูุฑุช ูููุง ุดููุฉ ู ุดุงูู ุจุชุฃุซุฑ ุนูู ุงูู Performance:
1.ุงูู Allocations ูุชูุฑ (ุงุณุชููุงู ููู ูู ูุฑู): ูู ู ุง ุจุชูุงุฏู ุนูู async methodุ ุงูู runtime ุจูุถุทุฑ ูุนู ู ุญุฌุฒ (Allocation) ูู ุงูู ูู ูุฑู ูุดููุฉ ุญุงุฌุงุช: ุงูู State machine objectุ ุงูู awaitersุ ูุงูู tasks. ูุชุฑ ุงูู allocations ุฏู ุจูุนู ู ุถุบุท ุนูู ุงูู ูู ูุฑู.
2. ุงูููู
ุจุงููุฑ ุดุงูู ุงูุญู
ู ููู:
ุงูู C# compiler ูู ุงููู ุจูููู
ุจูู ุงูุดุบู ุงูุชูููุ ูู ุงููู ุจูุจูู ุงูู state machineุ ููู ุงููู ุจูุฑุจุท ุงูู awaitersุ ููู ุงููู ุจูุนู
ู scheduling ููู continuations. ุงูู runtime ููุณู ูู ุงูุญูููุฉ ู
ุด ูุงูู
ูุนูู ุฅูู asyncุ ูู ู
ุฌุฑุฏ ุจูููุฐ ุงูููุฏ ุงููู ุงูููู
ุจุงููุฑ ุนู
ูู.
3. ุชุนููุฏ ุงูู Async Implementation: ูู ููุฑุช ุชูุชุญ ุงูู Intermediate Language (IL) ูููุฏ ููู asyncุ ูุชุชุตุฏู ู ู ุญุฌู ุงูููุฏ ุงูุถุฎู ูุงูู ุนูุฏ ุฌุฏูุง ุงููู ุงุชููุฏ ู ู ู ูุซูุฏ ูุงูุช ูู ุงูุฃุตู ุณุทุฑูู!
Enter Runtime Async (.NET 11)
ู
ู ููุง ุฌุช ุงูููุฑุฉ ุงูุฌุฏูุฏุฉ ูู .NET 11 (ูุงููู ุจุฏุฃุช ุชุฌุงุฑุจูุง ูู .NET 10). ุงูููุฑุฉ ุจุจุณุงุทุฉ: ุจุฏู ู
ุง ุงูู compiler ูู ุงููู ููุนุฏ ูุจูู state machine ุถุฎู
ุฉ ูู
ุนูุฏุฉ ููู ู
ูุซูุฏุ ููู ู
ุงูุฎููุด ุงูู runtime ููุณู ูููู
ุงูู asyncุ
ูุนูู ุจุฏู ู ุง ูุงูุช ุงูุฏูุฑุฉ ุจุชู ุดู ูุฏู: C# Code โ Compiler builds State Machine โ Runtime executes the generated class
ุจูุช ุจุชู ุดู ูุฏู: C# Code โ Compiler lets Runtime manage it โ Runtime Async Engine takes over
ููุงุ ุงูู async ุงุชุญูู ูู First-class citizen ุฌูู ุงูู runtime ููุณู.
Architecture Difference
graph TD subgraph Classic Async A1[Async Method] --> B1[C# Compiler] B1 --> C1[State Machine Class Generated] C1 --> D1[Runtime Executes Class] end subgraph Runtime Async A2[Async Method] --> B2[C# Compiler] B2 --> C2[Compiler marks method for Runtime] C2 --> D2[Runtime Async Engine Manages Execution] end
Why This Matters
ุงูููุฑุฉ ุฏู ู ุด ู ุฌุฑุฏ ุชุบููุฑ ู ุนู ุงุฑูุ ุฏู ูููุง ุชุฃุซูุฑุงุช ุถุฎู ุฉ ุนูู ุชุทุจููุงุชู:
1. ุงูู Performance ุฃุญุณู (ุฃุฏุงุก ุฃุนูู): ูู ุง ุงูู runtime ูุฏูุฑ ุงูุนู ููุฉุ ุงูู allocations ุจุชูู ุจุดูู ู ูุญูุธุ ูุงูู objects ุงููู ุจุชุชูุฑูุช ุจุชุจูู ุฃููุ ูุฏู ุจูููู ุงูู overhead. ุฏู ุจููุฑู ุฌุฏูุง ูู ุงูู ASP.NET Core ูุงูู APIs ููู ุฃู High throughput system ุจูุณุชูุจู ุทูุจุงุช ูุชูุฑ.
2. ุถุบุท ุฃูู ุนูู ุงูู Garbage Collector (GC): ูู ุงูู Web servers ูุงูู Microservicesุ ูู ูุฉ ุงูู async methods ุงููู ุจุชุชููุฐ ูู ูู ุฑููููุณุช ู ูููุฉ. ูู ููููุง ุงูู allocationsุ ููููู ุงูุดุบู ุงููู ุงูู GC ู ุญุชุงุฌ ูุนู ููุ ูุจุงูุชุงูู ุงูุฃุจูููุดู ููุจูู ุฃุณุฑุน ูุฃูุซุฑ ุงุณุชูุฑุงุฑูุง.
3. ุงูู Async ููุจูู ุฃุฎู:
ูู ุจุนุถ ุงูุญุงูุงุช ุงูุญุฑุฌุฉ ุฌุฏูุง (Hot paths)ุ ุงูู
ุจุฑู
ุฌูู ูุงููุง ุจูุชุฌูุจูุง ุงุณุชุฎุฏุงู
async ุจุณุจุจ ุงูู overhead ุจุชุงุนู. ู
ุน ุงูู Runtime Asyncุ ุงูู overhead ุฏู ูููู ุฌุฏูุง.
Practical API Example
ุนุดุงู ูุญุณ ุจุญุฌู ุงูุชุบููุฑุ ุชุฎูู ุฅูู ุจุชุจูู API ุฒู ุฏู:
public async Task<User> GetUser()
{
var user = await db.Users.FindAsync(1);
return user;
}ุงูุฑููููุณุช ุงููุงุญุฏ ุงููู ุจูุฌู ููู API ุฏู ู
ู
ูู ูู
ุฑ ุจู 10 async calls ููู call ูููุง 2 await.
ูู ูู await ู
ู ุฏูู ูููุฑูุช State machine ู awaiter ููุนู
ู memory allocationุ ูุงูุช ุจุชุชููู
ูู Load ูุจูุฑ ุฌุฏูุง ุนูู ุงูุณูุฑูุฑ ู
ุน ุฒูุงุฏุฉ ุนุฏุฏ ุงูู
ุณุชุฎุฏู
ูู. ุงูู Runtime async ุจูููู ูู ุงูุญู
ู ุฏู ุจุดูู ุฌุฐุฑู.
The Journey: Preview 2 and .NET 10
ูุงุฒู ููุถุญ ุฅู ุงูู Runtime Async ูุณู ูู ุจุฏุงูุชู. ูุงูุช ุฏู ู ุฌุฑุฏ ุฎุทูุฉ ุฃููู ูุฅุซุจุงุช ุงูููุฑุฉ.
ููู ุงูููุฑุฉ ุฏู ููุณูุง ุจุฏุฃุช ุชุธูุฑ ู
ูุงู
ุญูุง ูู .NET 10. ูู ุงูุฅุตุฏุงุฑ ุฏูุ ุงูู Runtime Async ูุงู ู
ุชุงุญ ูู Experimental Preview. ููุช ุชูุฏุฑ ุชูุนูู ุนู ุทุฑูู ุฅุถุงูุฉ Flags ู
ุนููุฉ ูู ู
ูู ุงูู .csproj ุจุชุงุนู. ุงูู
ุดููุฉ ูู .NET 10 ุฅู ุงูู Core Framework ูุงูู Libraries ุงูุฃุณุงุณูุฉ (ุฒู ASP.NET Core) ู
ุงููุชุด ูุณู ุงุชุนู
ููุง Recompile ุนุดุงู ุชุณุชุฎุฏู
ุงูุชูููููุฌูุง ุฏูุ ููุงูุช ุงูููุงุฆุฏ ู
ุญุฏูุฏุฉ ุจููุฏู ุฃูุช ุจุณ.
ุงููุฏู ุนูู ุงูู
ุฏู ุงูุทููู ุฅู ุงูู async ูุจูู Native ุชู
ุงู
ูุง ูู ุงูู runtimeุ ูููุฑุจ ูู ุฃุฏุงุฆู ูุณุฑุนุชู ู
ู ุงูู Goroutines ูู ูุบุฉ Goุ ููุณู
ุญ ููู runtime ุฅูู ูุนู
ู Optimizations ุฃุนูุฏ ุจูุชูุฑ.
What Exactly is a State Machine?
ุนุดุงู ูููู ุงูุนุธู ุฉ ุงููู ูุงูุช ุจุชุญุตู ูู ุงูุทุฑููุฉ ุงููุฏูู ุฉ ูุงููู ุจุชุชุบูุฑ ุฏูููุชูุ ุฎูููุง ูุฑุฌุน ุฎุทูุฉ ููุฑุง ููุดุฑุญ ูุนูู ุฅูู State Machine ุจุจุณุงุทุฉ.
ุงูู State Machine ูู ูุธุงู ุจูุชููู ู ู:
- ุงูู States (ุญุงูุงุช): ุงูุญุงูุงุช ุงูู ุฎุชููุฉ ุงููู ู ู ูู ุงููุธุงู ูููู ูููุง.
- ุงูู Transitions (ุงูุชูุงูุงุช): ุงููููุฉ ู ู ุญุงูุฉ ูุญุงูุฉ ุชุงููุฉ ุจูุงุกู ุนูู ุญุฏุซ ู ุนูู (Event).
ูุนูู ุงูุจุฑูุงู ุฌ ู ุด ุจูู ุดู ูู ุฎุท ู ุณุชููู ู ู ููู ูุชุญุช ูุฎูุงุตุ ูุฃุ ุฏู ุจูุชููู ุจูู ุญุงูุงุช.
Traffic Light Analogy
ุชุฎูู ุฅุดุงุฑุฉ ุงูู ุฑูุฑุ ุงูุญุงูุงุช ุงููู ูููุง ูู: Redุ Yellowุ Green. ูุงูุงูุชูุงูุงุช ุจุชููู: Red - Green - Yellow - Red. ุฏู State Machine ุจุณูุทุฉ ุฌุฏูุงุ ูุฃู ูููุง States ููููุง Transitions.
ูู ูููุชุจูุง ููุฏ ูุชุจูู ุดุจู ูุฏู:
enum TrafficLightState
{
Red,
Green,
Yellow
}
TrafficLightState state = TrafficLightState.Red;
switch(state)
{
case TrafficLightState.Red:
state = TrafficLightState.Green;
break;
case TrafficLightState.Green:
state = TrafficLightState.Yellow;
break;
case TrafficLightState.Yellow:
state = TrafficLightState.Red;
break;
}Relation to Async
ูู ุง ุจุชูุชุจ ููุฏ async ุฒู ุฏู:
public async Task<int> GetNumber()
{
await Task.Delay(1000);
return 5;
}ุงูู
ุดููุฉ ุฅู ุงูู
ูุซูุฏ ุฏู ูุชูุตู ุนูุฏ ุงูู await ููุชุชููู (Pause)ุ ูุจุนุฏูู ุชุฑุฌุน ุชูู
ู ุดุบู ุจุนุฏูู ูู
ุง ุงูู Task ุชุฎูุต.
ุนุดุงู ุงููุธุงู
ููุชูุฑ ูู ูุงู ูุงูู ููู ุจุงูุธุจุท ูู
ุง ูุฑุฌุนุ ูุงุฒู
ูุณุชุฎุฏู
State Machine.
ุงูู Compiler ุจูุญูู ุงูููุฏ ูุญุงูุงุช (States):
- ุงูู State 0: ุจุฏุงูุฉ ุงูู ูุซูุฏ.
- ุงูู State 1: ุจุนุฏ ู
ุง ุงูู
Task.Delayูุฎูุต. - ุงูู State 2: ููุงูุฉ ุงูู ูุซูุฏ ูุฅุฑุฌุงุน ุงููุชูุฌุฉ.
ุดูู ุงูุชูููุฐ ุงูู ุจุณุท ุจูููู ูุฏู:
int state = 0;
void MoveNext()
{
if(state == 0)
{
state = 1;
// Schedule continuation
Task.Delay(1000).ContinueWith(_ => MoveNext());
return;
}
if(state == 1)
{
Console.WriteLine(5);
}
}ูู ู
ุฑุฉ ุงูู Task ุจุชุฎูุตุ ุจุชูุงุฏู ุนูู MoveNext()ุ ูุงูู State machine ุจุชุนุฑู ูู ุงูู
ูุฑูุถ ุชูู
ู ู
ููู ุจูุงุกู ุนูู ููู
ุฉ ุงูู state.
State Machine Memory Layout
ุนุดุงู ุงูู async method ุชูุฏุฑ ุชููู ุงูุชูููุฐ ูุชุฑุฌุน ุงูู thread ูุชูู ู ุจุนุฏููุ ูุงุฒู ุชูุชูุฑ ูู ุญุงุฌุฉ: ูุงูุช ูุงููุฉ ูููุ ุงูู ุชุบูุฑุงุช ููู ุชูุง ุฅููุ ูุฅูู ุงูุฎุทูุฉ ุงูุฌุงูุฉ.
ูู ุฏู ุจูุชุฎุฒู ูู State Machine Object ูู ุงูุฐุงูุฑุฉ ุจูุจูู ุดููู ุงูุชูุฑูุจู ูุฏู:
{
"state": 0,
"local variables": "x = 5",
"awaiter": "TaskAwaiter object",
"continuation": "Next step to run"
}ูู ุนูุฏู ู
ูุซูุฏ ูููุง ู
ุชุบูุฑุงุช ุฒู int x = 5 ูุจู ุงูู awaitุ ุงูู State machine ูุงุฒู
ุชุญูุธ ููู
ุฉ x ุฌูุงูุง ุนุดุงู ูู
ุง ุงูุชูููุฐ ููู
ู ุจุนุฏ ุงูู await ููุงูู ุงูููู
ุฉ ู
ูุฌูุฏุฉ.
ุงูุฎูุงุตุฉ: ุงูู State Machine ูู ุงูุทุฑููุฉ ุงููู ุงูู .NET ุจูุณุชุฎุฏู
ูุง ุนุดุงู ููุณู
ุงูููุฏ ูู
ุฑุงุญูุ ูุญูุธ ู
ูุงู ุงูุชูููุ ููุณุชูู
ู ุงูุชูููุฐ ุจุนุฏูู. ูุจุชุณุชุฎุฏู
ูู async/awaitุ ู yield returnุ ู IAsyncEnumerable.
Deep Dive: The Real IL Code
ุฎูููุง ูุฏุฎู ุฃุนู ู ููุดูู ุงูู Intermediate Language (IL) ุงูุญูููู ุงููู ุงูู Compiler ุจูููุฏู ูู ุง ุจุชูุชุจ async/await.
ูู ููุฏู ุงูุฃุตูู ูู:
public async Task<int> GetNumberAsync()
{
await Task.Delay(1000);
return 5;
}ุงูู Compiler ุจูุนู ู ุฎุทูุชูู ูุจุงุฑ:
Step 1: Generating the State Machine Struct
ุจูููุฏ Struct ุงุณู
ูุง ุนุงุฏุฉ ุจูุจุฏุฃ ุจู <GetNumberAsync>d__0ุ ูุจูููู ุดูููุง ุชูุฑูุจูุง ูุฏู:
private struct GetNumberAsync_StateMachine : IAsyncStateMachine
{
public int state;
public AsyncTaskMethodBuilder<int> builder;
private TaskAwaiter awaiter;
public void MoveNext()
{
int result;
try
{
if (state == 0)
{
goto AfterAwait;
}
var task = Task.Delay(1000);
awaiter = task.GetAwaiter();
if (!awaiter.IsCompleted)
{
state = 0;
// Register continuation and pause
builder.AwaitUnsafeOnCompleted(ref awaiter, ref this);
return;
}
AfterAwait:
awaiter.GetResult();
result = 5;
}
catch (Exception ex)
{
builder.SetException(ex);
return;
}
builder.SetResult(result);
}
public void SetStateMachine(IAsyncStateMachine stateMachine)
{
builder.SetStateMachine(stateMachine);
}
}Step 2: Rewriting the Original Method
ุงูู ูุซูุฏ ุงูุฃุตููุฉ ุจุชุงุนุชู ุจุชุชุบูุฑ ูุชุจูู ู ุฌุฑุฏ Setup ููู State machine:
public Task<int> GetNumberAsync()
{
var stateMachine = new GetNumberAsync_StateMachine();
stateMachine.builder = AsyncTaskMethodBuilder<int>.Create();
stateMachine.state = -1; // Initial state
// Start the state machine
stateMachine.builder.Start(ref stateMachine);
return stateMachine.builder.Task;
}Understanding the Key Components:
- ุงูู
state: ุจูุญุฏุฏ ุฅุญูุง ููู (ู ุซูุงู-1ูุนูู ุงูุจุฏุงูุฉุ0ูุนูู ุจุนุฏ ุฃููawait). - ุงูู
MoveNext(): ุฏู ุฃูู ู ูุซูุฏ. ุงูู runtime ุจููุงุฏู ุนูููุง ูู ู ุฑุฉ ุงูููุฏ ุจูุญุชุงุฌ ููู ู ุดุบู. - ุงูู
awaiter: ุฏู ุงูุฃูุจุฌููุช ุงูู ุณุคูู ุฅูู ูุชุงุจุน ุงูู task ููุนุฑู ุฎูุตุช ููุง ูุฃ ููุณุชูู ู ุงูุชูููุฐ. - ุงูู
builder(AsyncTaskMethodBuilder): ุฏู ุงูู ุงูุณุชุฑู ุงููู ุจูุฏูุฑ ุงูุนู ููุฉุ ุจููุฑูุช ุงูู Taskุ ุจูุฑุฌุน ุงููุชูุฌุฉ ูู ุงูุขุฎุฑุ ูุจูุฏูุฑ ุงูู continuation.
Why is This So Heavy?
ูู ุฑูุฒุช ูู ุงููู ุจูุญุตูุ ูุชูุงูู ุงูู Flow ุจูู
ุดู ูุฏู:
Call Method โ Create StateMachine โ MoveNext() โ Reach await โ Register continuation โ Method returns โ Task finishes โ MoveNext() again โ Return result.
ูู ุงูุฎุทูุงุช ุฏู ุจุชุชุทูุจ ุฅูุชุงุฌ Structุ ุงุณุชุฎุฏุงู Builderุ ุฅุฏุงุฑุฉ Stateุ ูุชุณุฌูู Continuation. ุฏู ุจูุนู ู Overhead ูุจูุฑ ุฌุฏูุงุ ูุนุดุงู ูุฏู ุงูู Runtime Async ูู .NET 11 ุจูุญุงูู ูู ุณุญ ูู ุงูุชุนููุฏ ุฏู ููุฎูู ุงูู runtime ูุฏูุฑ ุงููุตุฉ ุฏู ู ุจุงุดุฑุฉ ุจู Objects ู Allocations ุฃูู.
ASP.NET Core & The Thread Pool Magic
ุจู ุง ุฅููุง ููู ูุง ุงูู Async ุดุบุงู ุฅุฒุงูุ ุฎูููุง ูุฑุจุทู ุจุฃูู ุญุงุฌุฉ ุจุชูุฑู ู ุนุงู ูู Backend Engineer: ุฅุฒุงู ุงูู ASP.NET Core ุจููุฏุฑ ูุฎุฏู ุขูุงู ุงูุฑููููุณุชุงุช ูู ููุณ ุงูููุช ุจุงุณุชุฎุฏุงู ุงูู ููุงููุฒู ุฏู.
ูู ุงูุชุฑุถูุง ุฅู ู
ุนูุฏูุงุด asyncุ ูุงูู API ุจูููู
Database ุจุชุงุฎุฏ 100ms ุนุดุงู ุชุฑุฏ. ุงูู Thread ุจุชุงุน ุงูุณูุฑูุฑ ูููุถู ูุงูู ู
ุณุชูู (Blocked) ุงูู 100ms ุฏูู ููู ู
ุด ุจูุนู
ู ุฃู ุญุงุฌุฉ ู
ููุฏุฉ. ูู ุนูุฏู 200 Thread ูู ุงูุณูุฑูุฑุ ูุฌุงูู 200 ุฑููููุณุช ูู ููุณ ุงููุญุธุฉ ุจูููู
ูุง ุงูู DBุ ุงูุณูุฑูุฑ ููู ูููู (Thread Starvation).
ููู ู
ุน ุงูู async/awaitุ ุงูุณุญุฑ ุจูุญุตู:
ูู
ุง ุงูููุฏ ุจููุตู ูู await db.Users.FirstAsync();ุ ุงูู runtime ุจูุณุฌู ุงูู continuationุ ูุจูุณูุจ (Release) ุงูู Thread ููุฑูุง.
ุงูู Thread ุฏู ุจูุฑุฌุน ููู Thread Pool ููุจูู ุฌุงูุฒ ูุฎุฏู
ุฑููููุณุช ุชุงูู ูุนู
ูู ุชุงูู.
The Restaurant Analogy
- ุจุฏูู Async: ุงูุฌุฑุณูู (Thread) ุจูุงุฎุฏ ุทูุจูุ ูุฑูุญ ูุฏูู ููู ุทุจุฎุ ูููุถู ูุงูู ูุฏุงู ุงูู ุทุจุฎ ุฑุจุน ุณุงุนุฉ ู ุณุชูู ุงูุฃูู ูุฌูุฒ ุนุดุงู ูุฌูุจูููู. ูู ุงูููุช ุฏู ู ุญุฏุด ุชุงูู ูู ุงูู ุทุนู ุจูุนุฑู ูุทูุจ.
- ู ุน Async: ุงูุฌุฑุณูู ุจูุงุฎุฏ ุทูุจูุ ูุฑู ูู ููู ุทุจุฎุ ููุฑูุญ ูุงุฎุฏ ุทูุจ ู ู ุชุฑุงุจูุฒุฉ ุชุงููุฉ. ูู ุง ุฃููู ูุฌูุฒุ ุงูู ุทุจุฎ ุจูุฑู ุฌุฑุณ (Task Completed)ุ ูุฃู ุฌุฑุณูู ูุงุถู ุจููุฌู ูุงุฎุฏ ุงูุฃูู ูููุตููููู.
ุฏู ุงูุณุจุจ ุงูุฑุฆูุณู ุฅู ASP.NET Core ููุฏุฑ ูุฎุฏู
10,000 ุฑููููุณุช ุจุงุณุชุฎุฏุงู
200 Threads ุจุณุ ูุฃู ู
ุนุธู
ุงูููุช ุงูุชุทุจูู ุจูููู ู
ุณุชูู (Waiting I/O) ุฒู ุฏุงุชุงุจูุฒ ุฃู Network ุฃู File system. ูุจู
ุง ุฅู ู
ููุด SynchronizationContext ูู ASP.NET Coreุ ุฃู Thread ูุงุถู ููุฏุฑ ููู
ู ุงูู
ูุซูุฏ ุจุนุฏ ุงูู await.
Advanced Under The Hood: Suspending Without a State Machine
ุงูุณุคุงู ุงููู ุจูุทุฑุญ ููุณู ููู ููุฏุณูู ุงูุซูุงู: ุฅุฒุงู ุงูู runtime ุจููุฏุฑ ูููู (Suspend) ุงูู ูุซูุฏ ู ู ุบูุฑ ู ุง ูุจูู State Machine ููุงุณ ุฃุตูุงูุ
ููุง ุจุชูุฌู ุงูุนุจูุฑูุฉ. ุงูู .NET ุจูุณุชุฎุฏู ุชูููู ุฃูุฑุจ ููู ุจูุญุตู ูู ูุบุงุช ุฒู Go ู Rust: ุจุฏู ู ุง ูููู ูู ุงูู ุชุบูุฑุงุช ูู Heap-allocated object (ุงูู State Machine)ุ ุงูู Runtime ุจูุนุชู ุฏ ุนูู ุชูููุฉ ุงุณู ูุง Stack Spilling ูุงุณุชุฎุฏุงู ุงูู Async Thunks.
ุงููู ุจูุญุตู ุฅู ุงูููุฏ ุจููุถู ุดุบุงู ุนูู ุงูู Call Stack ุงูุนุงุฏู. ูู
ุง ุจููุงุจู await ููุญุชุงุฌ ูุชูููุ ุงูู Runtime ุจูุงุฎุฏ โููุทุฉโ (Snapshot) ู
ู ุงููุฑูู
ุงูุญุงูู ุจุชุงุน ุงูู
ูุซูุฏ ุฏู ุนูู ุงูู Stack (ุจู
ุชุบูุฑุงุชูุง ููู ุญุงุฌุฉ) ูุจูููููุง (Spills it) ูู Heap-allocated memory ุฎูููุฉ ุฌุฏูุง (Continuation frame). ููู
ุง ุงูู Task ุชุฎูุตุ ุงูู Runtime ุจูุฑุฌุน ูู Restore ุงููุฑูู
ุฏู ุชุงูู ุนูู ุงูู Stack ุนู ุทุฑูู ุงูู Async Thunks ูููู
ู ุชูููุฐ ูุฃู ู
ููุด ุญุงุฌุฉ ุญุตูุช.
ุงูุฃุณููุจ ุฏู ุจูุฎูู ุงูู Execution ุณุฑูุน ุฌุฏูุงุ ูุงูู Allocations ุจุชุญุตู ุจุณ ูู ูุนูุงู ุงูู ูุซูุฏ ุงุญุชุงุฌุช ุชุณุชูู (ูู ุฎูุตุช Synchronously ู ุด ุจูุญุตู ุฃู Allocation ููุงุฆู).
More in .NET 11
.NET 11: Runtime Async V2
ูู ุงูุชุญุฏูุซ ุงูุฌุฏูุฏ (.NET 11 Preview 2)ุ ุงูุชุทูุฑ ุจูู ู ูุญูุธ ุฌุฏูุง. ุงูู Runtime Async ุฏุฎู ู ุฑุญูุฉ (V2)ุ ูุจุฏู ู ุง ูุงู ุงูููู ุจุงููุฑ ุจูุจูู ุงูู Classesุ ุงูู runtime ุจูู ุจูุฏูุฑ ุนู ููุฉ ุงูู Suspend ูุงูู Resume ุจููุณู.
Opting In
ูุฃู ุงูู
ูุฒุฉ ูุณู ูู ู
ุฑุญูุฉ ุงูู Previewุ ูุงุฒู
ุชูุนููุง ุจุฅูุฏู ูู ู
ูู ุงูู .csproj:
<PropertyGroup>
<Features>runtime-async=on</Features>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
</PropertyGroup>Cleaner Live Stack Traces
ุฃูุชุฑ ูุฑู ูุชุดููู ุจุนููู ูู ุงูู Stack Traces (ููุช ุงูู Debugging ูุงูู Profiling).
ูู ุงูุทุฑููุฉ ุงููุฏูู
ุฉุ ูู ุนูุฏู ู
ูุซูุฏุฒ ุจุชูุงุฏู ุจุนุถ: Main โ OuterAsync โ MiddleAsync โ InnerAsyncุ ุงูู Stack Trace ูุงู ุจูุจูู ู
ููุงู ุฒุจุงูุฉ (Frames ูุชูุฑ ู
ู AsyncMethodBuilderCore.Start ู MoveNext).
ู ุน ุงูู Runtime Asyncุ ุงูู Stack trace ุจูุจูู ูุธูู ุฌุฏุงู ูู ุจุงุดุฑ:
at Program.<<Main>$>g__InnerAsync|0_2() in Program.cs:line 24
at Program.<<Main>$>g__MiddleAsync|0_1() in Program.cs:line 14
at Program.<<Main>$>g__OuterAsync|0_0() in Program.cs:line 8
at Program.<Main>$(String[] args) in Program.cs:line 3
at Program.<Main>(String[] args)ู
ููุด ุฃู State machine infrastructure ุธุงูุฑุฉ! (ุฎูู ุจุงูู ุฅู ุงูู Exception Stack Traces ูุงูุช ูุฏู ูุฏู ูุธููุฉ ุจุณุจุจ ุงูู ExceptionDispatchInfoุ ุงูุชุญุณู ููุง ูู ุงูู Live stack traces ูุฃูุช ุจุชุนู
ู Debugging).
Debugging Improvements
ุฏูููุชู ุงูู Breakpoints ุจุชุดุชุบู ุตุญ ุฌูู ุงูู runtime-async methods. ุงูู Debugger ุงุชุนูู
ุฅุฒุงู ูุชุนุฑู ุนูู ุญุงุฌุฉ ุงุณู
ูุง async thunks ููุนู
ููุง Mapping ููููุฏ ุงูุฃุตูู ุจุชุงุนูุ ูุจุชูุฏุฑ ุชุนู
ู Step Over ููู await ุจุณูุงุณุฉ ุจุฏูู ู
ุง ุชุชูุทุท ูู ููุฏ ุงูู infrastructure ุงูู
ููุฏ.
JIT Improvements in Preview 2
ุชุญุฏูุซ .NET 11 Preview 2 ุฌุงุจ ู ุนุงู ุชุญุณููุงุช ูููุฉ ุฌุฏูุง ูู ุงูู JIT Compiler:
- Bounds Check Removal:
ูู ุงูู JIT ูุฏุฑ ูุชุฃูุฏ ุฅู ุงูุดุฑุท i + constant < length ุฏุงูู
ุงู ู
ุชุญููุ ุจูุดูู ุงูู Bounds check ุชู
ุงู
ุงู. ุฏู ุจูููู ุงูู Branching ูุจูุณุฑุน ุงูููุจุณ ุฌุฏูุง.
- Redundant Checked Context Removal:
ูู ุงูู checked blocks (ุงููู ุจุชุฑุงูุจ ุงูู Overflow ูู ุงูุนู
ููุงุช ุงูุญุณุงุจูุฉ)ุ ูู ุงูู JIT ุฃุซุจุช ุฅู ุงูููู
ู
ุณุชุญูู ุชุนู
ู Overflowุ ุจููุบู ุงูู check ุฏู ุนุดุงู ูุญุณู ุงูุฃุฏุงุก.
- Devirtualization in ReadyToRun (R2R):
ูู ุงูู OOPุ ุงูู Virtual calls ุจุชุญุชุงุฌ Runtime dispatch (ุชุญุฏูุฏ ุงููู ู ูุซูุฏ ูุชุชููุฐ ููุช ุงูุชุดุบูู). ุฏูููุชู ุงูู R2R (Ahead-of-Time compilation) ุจูู ููุฏุฑ ูุนู ู Devirtualize ููู ูุซูุฏุฒ ุงูุฌูููุฑูู ุงูุบูุฑ ู ุดุชุฑูุฉ ูููุงุฏููุง ุจุดูู ู ุจุงุดุฑุ ูุฏู ุฃุณุฑุน ุจูุชูุฑ.
- SVE2 Intrinsics:
ุฅุถุงูุฉ ุฏุนู ูุชุนููู ุงุช ARM SVE2 ุงูุฎุงุตุฉ ุจุงูู SIMD ูุงูู Math-heavy workloads.
VM Improvements
ุงูู Virtual Machine (CLR) ุฃุฎุฏุช ูุตูุจูุง ู ู ุงูุชุญุณููุงุช:
- Cached Interface Dispatch on Non-JIT Platforms:
ุนูู ู ูุตุงุช ุฒู iOS ุงููู ู ููุงุด JITุ ุงูู ูุงุฏุงุฉ ุนูู Interfaces ูุงูุช ุจุชุณุชุฎุฏู ู ุณุงุฑ ุจุทูุก (Generic fixup). ุฏูููุชู ุจููุง ูุณุชุฎุฏู ูุง Cached dispatch ุจุดูู ุงูุชุฑุงุถูุ ูุฏู ุณุฑูุน ุงูุฃุฏุงุก ูุฏุฑุฌุฉ ุชูุตู ูู 200 ุถุนู ูู ุงูููุฏ ุงูู ุนุชู ุฏ ุนูู ุงูู Interfaces ุจูุซุฑุฉ.
- Guid.NewGuid() on Linux:
ุจุฏู ู
ุง ุงูู runtime ูุงู ุจููุฑุฃ ู
ู ุงููุงูู /dev/urandomุ ุจูู ุจูุณุชุฎุฏู
ุงูู getrandom() System call ู
ุน Caching. ุงููุชูุฌุฉุ ุชุณุฑูุน ุจูุณุจุฉ 12% ูุฅูุชุงุฌ ุงูู GUIDs ุนูู ููููุณ.
- CoreCLR iOS-like Mode:
ุฃุถุงููุง Flag ุฌุฏูุฏ --dynamiccodecompiled false ุจูุฎูู ุงูู CoreCLR ุนูู ุงูุฏูุณูุชูุจ ูุชุตุฑู ูุฃูู ุดุบุงู ุนูู iOS (ุจูููู ุงูู JIT ููุดุบู ุงูู Interpreter). ุฏู ุจูุณุงุนุฏู ุชุชูุณุช ุจูุฆุฉ ุงูู AOT ูุฃูุช ุนูู ุฌูุงุฒู ู
ู ุบูุฑ ู
ุง ุชุถุทุฑ ุชุนู
ู Deploy ุนูู ู
ูุจุงูู.
Notes
- ุงูู
TaskvsValueTask: ูุฅุญูุง ุจูุชููู ุนู ุชูููู ุงูู Allocationsุ ุงูู .NET ูุงู ูุฏูValueTaskูุจู ูุฏู ูุญู ูุชูููู ุงูุญุฌุฒ ูู ุงูุฐุงูุฑุฉ ูู ุงูู Async method ูุชุฑุฌุน ุงููุชูุฌุฉ ุจุดูู ู ุชุฒุงู ู (Synchronously). ุงูู Runtime Async ุจูุงุฎุฏ ุงูููุฑุฉ ุฏู ูููู ุฃุนูู ูุจูููู ุงูู Overhead ุญุชู ูู ุงูู Asynchronous paths ุงูุญููููุฉ. - ุงูู System.Linq.AsyncEnumerable: ู
ู ุงูุชุบููุฑุงุช ุงููููุฉ ูู .NET 10 ุงูู
ุฑุชุจุทุฉ ุจุงูู Asyncุ ุฅู ู
ุงููุฑูุณููุช ุฃุถุงูุช
System.Linq.AsyncEnumerableูุฌุฒุก Native ู ู ุงูู .NET. ูุจู ูุฏูุ ูู ููุช ุนุงูุฒ ุชุณุชุฎุฏู LINQ ู ุนIAsyncEnumerableุ ููุช ุจุชุถุทุฑ ุชูุฒู ุจุงููุฏุฌ ุฎุงุฑุฌูุฉ (System.Linq.Asyncู ู Ix.NET). ู ู ุฃูู .NET 10ุ ุงูุฏุนู ุฏู ุจูู ู ุฏู ุฌุ ูุฏู ุจูุนูุณ ุชูุฌู ู ุงููุฑูุณููุช ุฅู ุงูู Async ูุจูู ุฌุฒุก ู ุชุฃุตู (First-class) ูู ุงูู ูุตุฉ ูุงูู Runtime.