.NET 11 Preview 3: Union Type, Runtime Async và loạt cải tiến đáng chú ý

Posted on: 4/25/2026 5:16:08 AM

Microsoft vừa phát hành .NET 11 Preview 3 vào ngày 14/04/2026, mang theo hàng loạt cải tiến quan trọng từ ngôn ngữ C#, runtime, ASP.NET Core đến Entity Framework Core. Đây là bản preview thứ ba trong lộ trình hướng tới bản GA vào tháng 11/2026, và lần này có một tính năng mà cộng đồng chờ đợi rất lâu: Union Types.

Union Types Tính năng ngôn ngữ C# được chờ đợi nhất
Zstandard Thuật toán nén mới trong System.IO
Runtime Async Chuyển từ preview sang stable
HTTP/3 Xử lý request sớm hơn, giảm latency

1. C# Union Types — Tính năng được chờ đợi nhất

Union Types là tính năng ngôn ngữ lớn nhất trong .NET 11 Preview 3. Nếu bạn từng dùng TypeScript, F#, hoặc Rust, bạn sẽ thấy quen thuộc — đây là cách khai báo một biến có thể là một trong nhiều kiểu dữ liệu cụ thể, nhưng được kiểm tra tại compile-time.

1.1. Vấn đề Union Types giải quyết

Trước .NET 11, khi một method có thể trả về nhiều kiểu kết quả khác nhau, bạn thường phải:

  • Dùng object rồi cast — mất type safety
  • Tạo abstract class/interface hierarchy — boilerplate nhiều
  • Dùng OneOf<T1,T2> từ NuGet — không phải first-class citizen
  • Dùng Result<T> pattern — convention, không compiler-enforced
// TRƯỚC .NET 11: Dùng class hierarchy
public abstract record PaymentResult;
public record PaymentSuccess(string TransactionId) : PaymentResult;
public record PaymentFailed(string Error) : PaymentResult;
public record PaymentPending(DateTime RetryAfter) : PaymentResult;

// Phải check type manually
if (result is PaymentSuccess success) { ... }
else if (result is PaymentFailed failed) { ... }
// Compiler KHÔNG cảnh báo nếu bạn quên handle PaymentPending!
// .NET 11: Union Types
union PaymentResult = PaymentSuccess | PaymentFailed | PaymentPending;

public record PaymentSuccess(string TransactionId);
public record PaymentFailed(string Error);
public record PaymentPending(DateTime RetryAfter);

// Pattern matching EXHAUSTIVE — compiler buộc bạn handle hết
string message = result switch
{
    PaymentSuccess s => $"Paid: {s.TransactionId}",
    PaymentFailed f => $"Error: {f.Error}",
    PaymentPending p => $"Retry at: {p.RetryAfter}",
    // Không cần default — compiler biết đã đủ!
};

Exhaustive Pattern Matching

Điểm mạnh nhất của Union Types là compiler bắt buộc bạn xử lý mọi case. Nếu sau này thêm một variant mới (ví dụ PaymentRefunded), mọi switch expression chưa handle variant đó sẽ báo lỗi tại compile-time — không còn bug ẩn lúc runtime.

1.2. Ứng dụng thực tế

// API Error handling rõ ràng hơn
union ApiResponse<T> = Success<T> | ValidationError | NotFound | Unauthorized;

public async Task<ApiResponse<Order>> GetOrder(int id)
{
    if (!IsAuthenticated) return new Unauthorized();

    var order = await _db.Orders.FindAsync(id);
    if (order is null) return new NotFound();

    return new Success<Order>(order);
}

// Controller xử lý
var response = await _service.GetOrder(id);
return response switch
{
    Success<Order> s => Ok(s.Value),
    ValidationError v => BadRequest(v.Errors),
    NotFound => NotFound(),
    Unauthorized => Unauthorized(),
};

2. Runtime Async — Từ Preview sang Stable

Một trong những thay đổi quan trọng nhất ở tầng runtime: Runtime Async đã loại bỏ yêu cầu opt-in qua preview API. Điều này có nghĩa async/await giờ được xử lý trực tiếp bởi runtime thay vì compiler-generated state machine.

graph LR
    A["async/await Code"] --> B{"Runtime Async
.NET 11"} B --> C["JIT xử lý trực tiếp
Không state machine"] B --> D["Giảm allocation
Ít GC pressure"] A --> E{"Cách cũ
.NET 10"} E --> F["Compiler tạo
State Machine class"] E --> G["Nhiều allocation
Task objects"] style B fill:#4CAF50,stroke:#fff,color:#fff style E fill:#e94560,stroke:#fff,color:#fff style C fill:#f8f9fa,stroke:#4CAF50,color:#2c3e50 style D fill:#f8f9fa,stroke:#4CAF50,color:#2c3e50 style F fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style G fill:#f8f9fa,stroke:#e94560,color:#2c3e50

Hình 1: So sánh cách xử lý async giữa .NET 10 và .NET 11

Lợi ích thực tế:

  • Giảm memory allocation: Không còn state machine class được tạo cho mỗi async method
  • Giảm GC pressure: Ít object ngắn hạn cần thu gom
  • Stack traces sạch hơn: Debug async code dễ đọc hơn vì không có MoveNext() lộn xộn
  • Không cần thay đổi code: Chỉ cần target .NET 11, performance tự cải thiện

3. Zstandard Compression — Nén nhanh hơn, nhỏ hơn

Zstandard (zstd) — thuật toán nén do Facebook phát triển — chính thức gia nhập System.IO.Compression trong .NET 11. Trước đó, bạn phải dùng NuGet package bên thứ ba.

Thuật toán Tỷ lệ nén Tốc độ nén Tốc độ giải nén Use case
Zstandard Cao Rất nhanh Cực nhanh API responses, real-time data
Brotli Rất cao Chậm Nhanh Static assets, CDN
Gzip Trung bình Trung bình Nhanh Backward compatibility
Deflate Thấp Nhanh Nhanh Legacy, ZIP files

3.1. ASP.NET Core Response Compression

// ASP.NET Core tự động hỗ trợ Zstandard response compression
builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
    options.Providers.Add<ZstandardCompressionProvider>();
    options.Providers.Add<BrotliCompressionProvider>();
    options.Providers.Add<GzipCompressionProvider>();
});

// Automatic request decompression cũng được hỗ trợ
builder.Services.AddRequestDecompression();

Ngoài response compression, .NET 11 cũng thêm automatic request decompression — server tự giải nén request body mà client gửi lên, hữu ích cho API nhận payload lớn.

4. JIT Compiler — Tối ưu hiệu năng sâu

JIT compiler trong .NET 11 Preview 3 cải thiện ba lĩnh vực quan trọng:

4.1. Switch Statement Optimization

JIT giờ tạo jump table hiệu quả hơn cho switch statements, đặc biệt khi pattern matching với Union Types — kết hợp hoàn hảo với tính năng ngôn ngữ mới.

4.2. Bounds Check Elimination

// JIT tự loại bỏ bounds check khi chứng minh được index an toàn
Span<int> data = stackalloc int[100];
for (int i = 0; i < data.Length; i++)
{
    data[i] = i * 2; // Không cần bounds check — JIT biết i < Length
}

4.3. Cast Optimization

Kiểm tra kiểu (is, as, cast) giờ nhanh hơn nhờ JIT tái sử dụng kết quả type check trước đó trong cùng method, tránh truy vấn method table nhiều lần.

5. System.Text.Json — Kiểm soát tốt hơn

.NET 11 bổ sung khả năng kiểm soát chi tiết hơn cho JSON serialization:

// Kiểm soát naming policy chi tiết hơn
var options = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    // MỚI: Control ignore behavior cho default values
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
};

// Union Types kết hợp JSON serialization
union Shape = Circle | Rectangle | Triangle;

// Tự động serialize/deserialize với discriminator
string json = JsonSerializer.Serialize<Shape>(new Circle(5.0));
// {"$type":"Circle","radius":5.0}

6. Entity Framework Core 11 — Query hiệu quả hơn

6.1. ChangeTracker.GetEntriesForState()

API mới tránh việc chạy change detection không cần thiết khi bạn chỉ muốn lấy entries ở một state cụ thể:

// TRƯỚC: Trigger full change detection
var modified = context.ChangeTracker.Entries()
    .Where(e => e.State == EntityState.Modified);

// .NET 11: Chỉ lấy entries ở state cần thiết, không scan toàn bộ
var modified = context.ChangeTracker
    .GetEntriesForState(EntityState.Modified);

6.2. SQL Generation — Loại bỏ JOIN thừa

EF Core 11 thông minh hơn trong việc phát hiện và loại bỏ các JOIN không cần thiết trong câu SQL được generate. Với các query phức tạp, điều này có thể giảm đáng kể execution time.

6.3. SQL Server JSON APIs mới

// Truy vấn JSON column trực tiếp từ LINQ
var orders = await context.Orders
    .Where(o => EF.Functions.JsonContains(
        o.Metadata, """{"priority": "high"}"""))
    .ToListAsync();

7. HTTP/3 trong ASP.NET Core — Xử lý sớm hơn

ASP.NET Core 11 cải thiện HTTP/3 bằng cách bắt đầu xử lý request sớm hơn trong pipeline, giảm latency cho first byte. Kết hợp với Zstandard compression, đây là bước tiến đáng kể cho Web Performance.

graph TD
    A["Client gửi request
HTTP/3 + QUIC"] --> B["Kestrel nhận stream"] B --> C{"Xử lý sớm hơn
.NET 11"} C --> D["Parse headers
ngay khi nhận"] D --> E["Bắt đầu middleware
pipeline"] E --> F["Response + Zstd
compression"] style C fill:#e94560,stroke:#fff,color:#fff style F fill:#4CAF50,stroke:#fff,color:#fff

Hình 2: HTTP/3 pipeline cải tiến trong .NET 11

8. SafeFileHandle & RandomAccess — Mở rộng Pipe Support

SafeFileHandleRandomAccess giờ hỗ trợ pipe (named pipes, anonymous pipes), cho phép dùng cùng API cho cả file I/O và inter-process communication:

// Dùng RandomAccess API cho pipe — mới trong .NET 11
using var pipe = new NamedPipeServerStream("myPipe");
await pipe.WaitForConnectionAsync();

var handle = pipe.SafePipeHandle;
// Giờ có thể dùng RandomAccess patterns cho pipe I/O
byte[] buffer = new byte[1024];
int bytesRead = await RandomAccess.ReadAsync(
    handle, buffer, fileOffset: 0);

9. Regex — Hỗ trợ Unicode Newlines

Regex engine trong .NET 11 nhận diện tất cả Unicode newline sequences, không chỉ \r\n\n:

  • \n — Line Feed (U+000A)
  • \r\n — Carriage Return + Line Feed
  • \r — Carriage Return (U+000D)
  • \u0085 — Next Line (NEL)
  • \u2028 — Line Separator
  • \u2029 — Paragraph Separator

Breaking Change tiềm ẩn

Nếu regex của bạn dùng . (dot) với RegexOptions.Multiline, hành vi có thể thay đổi vì giờ dot không match thêm các Unicode newlines mới. Kiểm tra lại regex patterns nếu xử lý text từ nhiều nguồn quốc tế.

10. Container Images — Cryptographic Signing

.NET 11 container images giờ được ký điện tử, cho phép bạn verify tính toàn vẹn của image trước khi deploy. Đây là bước quan trọng cho supply chain security trong CI/CD pipeline.

# Verify .NET 11 container image signature
cosign verify mcr.microsoft.com/dotnet/aspnet:11.0-preview.3 \
  --certificate-identity-regexp ".*microsoft.*" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com"

11. SDK — Cải tiến Developer Experience

Tính năng Mô tả Lợi ích
Solution Filters CLI Chỉnh sửa solution filters từ command line Tự động hóa CI/CD, không cần mở VS
Multi-file entry points Chia file-based app thành nhiều file Script-style apps phức tạp hơn mà vẫn gọn
dotnet run -e Truyền env vars từ command line Không cần file .env hay launchSettings.json
dotnet watch + Aspire Hot reload hỗ trợ Aspire apps Dev loop nhanh hơn cho distributed apps

12. Lộ trình .NET 11

Tháng 2/2026
Preview 1 — Các tính năng đầu tiên, runtime improvements cơ bản.
Tháng 3/2026
Preview 2 — EF Core improvements, SDK enhancements.
Tháng 4/2026
Preview 3 (hiện tại) — Union Types, Runtime Async stable, Zstandard, HTTP/3 improvements.
Tháng 5-9/2026
Preview 4-7 — Tiếp tục hoàn thiện tính năng, stabilization.
Tháng 10/2026
RC 1 & RC 2 — Release candidates, feature-complete.
Tháng 11/2026
.NET 11 GA — Bản chính thức, STS (Standard Term Support) 18 tháng.

STS vs LTS

.NET 11 là bản STS (Standard Term Support — 18 tháng). Nếu cần LTS (3 năm), hãy ở lại .NET 10. Tuy nhiên, nếu bạn muốn trải nghiệm Union Types và Runtime Async ngay, .NET 11 là lựa chọn đáng cân nhắc cho các dự án mới.

13. Nên upgrade lên .NET 11 Preview không?

  • Side projects & experiments: Hoàn toàn nên — đặc biệt để làm quen Union Types
  • Greenfield projects: Cân nhắc nếu timeline cho phép wait đến GA (11/2026)
  • Production apps: Chờ ít nhất RC1, tốt nhất là GA + 1-2 servicing updates
  • Thư viện/NuGet packages: Bắt đầu test compatibility sớm, nhưng chưa phát hành targeting .NET 11

Nguồn tham khảo