
Sử dụng cancellation token trong ASP.NET Core
February 23, 2025Trong ASP.NET Core, cancellation token đóng vai trò quan trọng trong việc tối ưu hóa tài nguyên bằng cách dừng các tác vụ không cần thiết khi chúng không còn được yêu cầu nữa. Điều này đặc biệt quan trọng trong phát triển web, nơi tài nguyên máy chủ có giới hạn và hiệu suất phản hồi nhanh là yếu tố quyết định trải nghiệm người dùng. Việc triển khai cancellation token trong API cho phép dừng các tác vụ dài hạn một cách hiệu quả, giảm lãng phí tài nguyên tính toán và nâng cao hiệu suất hệ thống.
Ví dụ sau đây định nghĩa một endpoint RESTful thực hiện một tác vụ giả lập chạy lâu và sử dụng CancellationToken để dừng tiến trình khi cần.
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Hosting;
using System.Threading;
using System.Threading.Tasks;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/heavy-operation", async (CancellationToken ct) =>
{
bool operationCompleted = await HeavyOperationAsync(ct);
if (ct.IsCancellationRequested)
{
return Results.StatusCode(499); // Client đã hủy request
}
return operationCompleted ? Results.Ok() : Results.StatusCode(500);
});
async Task<bool> HeavyOperationAsync(CancellationToken cancellationToken)
{
for (int i = 0; i < 5; i++)
{
if (cancellationToken.IsCancellationRequested)
{
return false; // Dừng tác vụ một cách an toàn
}
await Task.Delay(1000); // Giả lập xử lý công việc
}
return true;
}
app.Run();
Trong đoạn code trên, endpoint /heavy-operation thực hiện một tác vụ giả lập chạy lâu. CancellationToken (ct) được truyền vào như một tham số, cho phép dừng tiến trình nếu client hủy request. Nếu hủy request xảy ra, API trả về HTTP 499 (Client Closed Request), thể hiện rằng tác vụ đã bị gián đoạn. Phương thức HeavyOperationAsync chạy vòng lặp 5 lần, mỗi lần trì hoãn 1 giây để mô phỏng công việc nặng. Trong mỗi vòng lặp, kiểm tra cancellationToken.IsCancellationRequested. Nếu true, tiến trình sẽ kết thúc ngay lập tức, giúp tránh lãng phí tài nguyên. Điều này đảm bảo rằng ngay khi một yêu cầu bị hủy, hệ thống không tiếp tục thực thi tác vụ không cần thiết.
Client có thể khởi tạo một request HTTP và sau đó hủy request trước khi hoàn thành. Đoạn mã sau minh họa cách HttpClient sử dụng CancellationTokenSource để hủy một request đang chờ xử lý.
using var cts = new CancellationTokenSource();
var httpClient = new HttpClient();
// Gửi yêu cầu HTTP
var task = httpClient.GetAsync("<http://localhost:5000/heavy-operation>", cts.Token);
// Hủy request sau 3 giây
await Task.Delay(3000);
cts.Cancel();
try
{
await task; // Nếu request bị hủy, sẽ throw TaskCanceledException
}
catch (TaskCanceledException)
{
Console.WriteLine("Yêu cầu đã bị hủy.");
}
Quy trình hủy yêu cầu diễn ra theo các bước sau. Trước tiên, CancellationTokenSource (cts) được tạo để kiểm soát trạng thái hủy. Sau đó, HttpClient gửi request đến /heavy-operation và truyền cts.Token vào. Tiếp theo, cts.Cancel() được gọi sau 3 giây, gửi tín hiệu hủy đến server. Nếu server đang xử lý tác vụ, nó sẽ nhận tín hiệu hủy và kết thúc sớm. Phía client, TaskCanceledException sẽ được throw và được bắt để xác nhận rằng yêu cầu đã bị hủy thành công. Cách tiếp cận này giúp client có thể chủ động hủy các request không cần thiết, giảm tải cho máy chủ và cải thiện tốc độ phản hồi.
Cancellation token được sử dụng rộng rãi trong nhiều tình huống để tối ưu hiệu suất hệ thống. Một số trường hợp điển hình bao gồm xử lý tác vụ nền (background jobs) như xử lý batch hoặc nhập xuất dữ liệu khi không còn cần thiết, hủy request HTTP khi người dùng điều hướng khỏi trang hoặc ngừng chờ phản hồi, hủy các quy trình do người dùng khởi tạo như tạo báo cáo hoặc truy vấn dữ liệu lớn, thiết lập giới hạn thời gian (timeout operations) để dừng tiến trình nếu vượt quá thời gian xử lý cho phép, dừng các tác vụ tốn tài nguyên như tính toán phức tạp để giải phóng CPU, hủy tác vụ song song khi một task trong nhóm thất bại để tiết kiệm tài nguyên, kiểm soát quy trình làm việc (workflow operations) để hủy một workflow dài hoặc một bước cụ thể trong workflow và xử lý streaming dữ liệu để dừng truyền dữ liệu nếu client ngắt kết nối hoặc ngừng tiêu thụ dữ liệu.
Ngoài cách xử lý cơ bản, có thể áp dụng cancellation token vào các trường hợp phức tạp hơn như chuỗi cancellation tokens (linked cancellation tokens) để hủy tác vụ trên nhiều tiến trình liên kết trong hệ thống phân tán, hủy tác vụ trong microservices khi một microservice gặp lỗi để các tác vụ liên quan trên các dịch vụ khác có thể bị hủy theo, hoặc đảm bảo rằng khi ứng dụng ASP.NET Core tắt, các request đang xử lý cũng kết thúc một cách có kiểm soát. Việc áp dụng các chiến lược này giúp hệ thống bền vững, tiết kiệm tài nguyên và nâng cao trải nghiệm người dùng.
Sử dụng cancellation token trong ASP.NET Core là một kỹ thuật quan trọng giúp tối ưu tài nguyên, giảm tải máy chủ và tăng cường hiệu suất API. Việc cho phép hủy các tác vụ không cần thiết đảm bảo ứng dụng hoạt động hiệu quả và phản hồi nhanh.
Anh em có thể nghiên cứu sâu hơn về chuỗi cancellation tokens, các mô hình hủy tác vụ trong hệ thống phân tán và xử lý lỗi nâng cao, từ đó thiết kế hệ thống linh hoạt và hiệu quả hơn.