.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
Table of contents
- 1. C# Union Types — Tính năng được chờ đợi nhất
- 2. Runtime Async — Từ Preview sang Stable
- 3. Zstandard Compression — Nén nhanh hơn, nhỏ hơn
- 4. JIT Compiler — Tối ưu hiệu năng sâu
- 5. System.Text.Json — Kiểm soát tốt hơn
- 6. Entity Framework Core 11 — Query hiệu quả hơn
- 7. HTTP/3 trong ASP.NET Core — Xử lý sớm hơn
- 8. SafeFileHandle & RandomAccess — Mở rộng Pipe Support
- 9. Regex — Hỗ trợ Unicode Newlines
- 10. Container Images — Cryptographic Signing
- 11. SDK — Cải tiến Developer Experience
- 12. Lộ trình .NET 11
- 13. Nên upgrade lên .NET 11 Preview không?
- Nguồn tham khảo
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.
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
objectrồ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
SafeFileHandle và RandomAccess 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 và \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
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
Disclaimer: The opinions expressed in this blog are solely my own and do not reflect the views or opinions of my employer or any affiliated organizations. The content provided is for informational and educational purposes only and should not be taken as professional advice. While I strive to provide accurate and up-to-date information, I make no warranties or guarantees about the completeness, reliability, or accuracy of the content. Readers are encouraged to verify the information and seek independent advice as needed. I disclaim any liability for decisions or actions taken based on the content of this blog.