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 ุจูŠุฎู„ู‚ ู…ู† ุงู„ุนุฏู…:

  1. ูƒู„ุงุณ ุฃูˆ Struct ุฌุฏูŠุฏุฉ ุชู…ุงู…ู‹ุง.
  2. ู…ู†ุทู‚ State Machine ูƒุงู…ู„.
  3. ุงู„ู€ Builder ุงู„ู„ูŠ ุจูŠุจู†ูŠ ูˆูŠุฏูŠุฑ ุงู„ู€ Task.
  4. ุงู„ู€ 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 ู‡ูˆ ู†ุธุงู… ุจูŠุชูƒูˆู† ู…ู†:

  1. ุงู„ู€ States (ุญุงู„ุงุช): ุงู„ุญุงู„ุงุช ุงู„ู…ุฎุชู„ูุฉ ุงู„ู„ูŠ ู…ู…ูƒู† ุงู„ู†ุธุงู… ูŠูƒูˆู† ููŠู‡ุง.
  2. ุงู„ู€ 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:

  1. ุงู„ู€ state: ุจูŠุญุฏุฏ ุฅุญู†ุง ููŠู† (ู…ุซู„ุงู‹ -1 ูŠุนู†ูŠ ุงู„ุจุฏุงูŠุฉุŒ 0 ูŠุนู†ูŠ ุจุนุฏ ุฃูˆู„ await).
  2. ุงู„ู€ MoveNext(): ุฏูŠ ุฃู‡ู… ู…ูŠุซูˆุฏ. ุงู„ู€ runtime ุจูŠู†ุงุฏูŠ ุนู„ูŠู‡ุง ูƒู„ ู…ุฑุฉ ุงู„ูƒูˆุฏ ุจูŠุญุชุงุฌ ูŠูƒู…ู„ ุดุบู„.
  3. ุงู„ู€ awaiter: ุฏู‡ ุงู„ุฃูˆุจุฌูŠูƒุช ุงู„ู…ุณุคูˆู„ ุฅู†ู‡ ูŠุชุงุจุน ุงู„ู€ task ูˆูŠุนุฑู ุฎู„ุตุช ูˆู„ุง ู„ุฃ ูˆูŠุณุชูƒู…ู„ ุงู„ุชู†ููŠุฐ.
  4. ุงู„ู€ 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

Asynchronous Programming

ุจู…ุง ุฅู†ู†ุง ูู‡ู…ู†ุง ุงู„ู€ 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:

  1. Bounds Check Removal:

ู„ูˆ ุงู„ู€ JIT ู‚ุฏุฑ ูŠุชุฃูƒุฏ ุฅู† ุงู„ุดุฑุท i + constant < length ุฏุงูŠู…ุงู‹ ู…ุชุญู‚ู‚ุŒ ุจูŠุดูŠู„ ุงู„ู€ Bounds check ุชู…ุงู…ุงู‹. ุฏู‡ ุจูŠู‚ู„ู„ ุงู„ู€ Branching ูˆุจูŠุณุฑุน ุงู„ู„ูˆุจุณ ุฌุฏู‹ุง.

  1. Redundant Checked Context Removal:

ููŠ ุงู„ู€ checked blocks (ุงู„ู„ูŠ ุจุชุฑุงู‚ุจ ุงู„ู€ Overflow ููŠ ุงู„ุนู…ู„ูŠุงุช ุงู„ุญุณุงุจูŠุฉ)ุŒ ู„ูˆ ุงู„ู€ JIT ุฃุซุจุช ุฅู† ุงู„ู‚ูŠู… ู…ุณุชุญูŠู„ ุชุนู…ู„ OverflowุŒ ุจูŠู„ุบูŠ ุงู„ู€ check ุฏู‡ ุนุดุงู† ูŠุญุณู† ุงู„ุฃุฏุงุก.

  1. Devirtualization in ReadyToRun (R2R):

ููŠ ุงู„ู€ OOPุŒ ุงู„ู€ Virtual calls ุจุชุญุชุงุฌ Runtime dispatch (ุชุญุฏูŠุฏ ุงู†ู‡ูŠ ู…ูŠุซูˆุฏ ู‡ุชุชู†ูุฐ ูˆู‚ุช ุงู„ุชุดุบูŠู„). ุฏู„ูˆู‚ุชูŠ ุงู„ู€ R2R (Ahead-of-Time compilation) ุจู‚ู‰ ูŠู‚ุฏุฑ ูŠุนู…ู„ Devirtualize ู„ู„ู…ูŠุซูˆุฏุฒ ุงู„ุฌูŠู†ูŠุฑูŠูƒ ุงู„ุบูŠุฑ ู…ุดุชุฑูƒุฉ ูˆูŠู†ุงุฏูŠู‡ุง ุจุดูƒู„ ู…ุจุงุดุฑุŒ ูˆุฏู‡ ุฃุณุฑุน ุจูƒุชูŠุฑ.

  1. SVE2 Intrinsics:

ุฅุถุงูุฉ ุฏุนู… ู„ุชุนู„ูŠู…ุงุช ARM SVE2 ุงู„ุฎุงุตุฉ ุจุงู„ู€ SIMD ูˆุงู„ู€ Math-heavy workloads.


VM Improvements

Virtual Machine - CLR

ุงู„ู€ Virtual Machine (CLR) ุฃุฎุฏุช ู†ุตูŠุจู‡ุง ู…ู† ุงู„ุชุญุณูŠู†ุงุช:

  1. Cached Interface Dispatch on Non-JIT Platforms:

ุนู„ู‰ ู…ู†ุตุงุช ุฒูŠ iOS ุงู„ู„ูŠ ู…ูู‡ุงุด JITุŒ ุงู„ู…ู†ุงุฏุงุฉ ุนู„ู‰ Interfaces ูƒุงู†ุช ุจุชุณุชุฎุฏู… ู…ุณุงุฑ ุจุทูŠุก (Generic fixup). ุฏู„ูˆู‚ุชูŠ ุจู‚ูˆุง ูŠุณุชุฎุฏู…ูˆุง Cached dispatch ุจุดูƒู„ ุงูุชุฑุงุถูŠุŒ ูˆุฏู‡ ุณุฑู‘ุน ุงู„ุฃุฏุงุก ู„ุฏุฑุฌุฉ ุชูˆุตู„ ู„ู€ 200 ุถุนู ููŠ ุงู„ูƒูˆุฏ ุงู„ู…ุนุชู…ุฏ ุนู„ู‰ ุงู„ู€ Interfaces ุจูƒุซุฑุฉ.

  1. Guid.NewGuid() on Linux:

ุจุฏู„ ู…ุง ุงู„ู€ runtime ูƒุงู† ุจูŠู‚ุฑุฃ ู…ู† ุงู„ูุงูŠู„ /dev/urandomุŒ ุจู‚ู‰ ุจูŠุณุชุฎุฏู… ุงู„ู€ getrandom() System call ู…ุน Caching. ุงู„ู†ุชูŠุฌุฉุŸ ุชุณุฑูŠุน ุจู†ุณุจุฉ 12% ู„ุฅู†ุชุงุฌ ุงู„ู€ GUIDs ุนู„ู‰ ู„ูŠู†ูƒุณ.

  1. CoreCLR iOS-like Mode:

ุฃุถุงููˆุง Flag ุฌุฏูŠุฏ --dynamiccodecompiled false ุจูŠุฎู„ูŠ ุงู„ู€ CoreCLR ุนู„ู‰ ุงู„ุฏูŠุณูƒุชูˆุจ ูŠุชุตุฑู ูƒุฃู†ู‡ ุดุบุงู„ ุนู„ู‰ iOS (ุจูŠู‚ูู„ ุงู„ู€ JIT ูˆูŠุดุบู„ ุงู„ู€ Interpreter). ุฏู‡ ุจูŠุณุงุนุฏูƒ ุชุชูŠุณุช ุจูŠุฆุฉ ุงู„ู€ AOT ูˆุฃู†ุช ุนู„ู‰ ุฌู‡ุงุฒูƒ ู…ู† ุบูŠุฑ ู…ุง ุชุถุทุฑ ุชุนู…ู„ Deploy ุนู„ู‰ ู…ูˆุจุงูŠู„.


Notes

  • ุงู„ู€ Task vs ValueTask: ูˆุฅุญู†ุง ุจู†ุชูƒู„ู… ุนู† ุชู‚ู„ูŠู„ ุงู„ู€ 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.