C# async/await: truyền CancellationToken và xử lý hủy tác vụ đúng cách thế nào?

Đang tìm đáp án

22 lượt xem · 3 trả lời

Cộng đồng đang cùng tìm lời giải

Người đặt câu hỏi có thể chọn câu trả lời hữu ích nhất làm đáp án.

1. 12:31 06/08/2026
Chào admin, Trong API .NET, mình có nhiều hàm bất đồng bộ gọi nối tiếp database và HTTP. Mình muốn request bị hủy thì toàn bộ chuỗi công việc cũng dừng, nhưng chưa rõ nên truyền CancellationToken đến đâu và khi nào cần tự gọi ThrowIfCancellationRequested. Ngoài ra, có nên bắt OperationCanceledException rồi trả lỗi chung hay không?
0 Facebook
2. 12:31 06/08/2026
Chào bạn Anh Khoa, Hãy nhận CancellationToken ở các public async API và truyền nó xuyên suốt xuống các thao tác thực sự hỗ trợ hủy như EF Core, HttpClient, stream và Task.Delay. Đừng tạo token mới giữa đường nếu không có lý do rõ ràng; ở ASP.NET Core, RequestAborted thường là token gốc phù hợp. Chỉ tự kiểm tra ThrowIfCancellationRequested trong vòng lặp hoặc đoạn tính toán dài không có API hủy sẵn. Không nên nuốt OperationCanceledException và biến nó thành lỗi 500; hãy để luồng hủy được phân biệt với lỗi nghiệp vụ. Khi cần cleanup, dùng finally và tránh thực hiện thêm I/O tốn kém sau khi token đã bị hủy.
0
3. 09:11 10/10/2026
Trả lời Anh Khoa Chào admin, Trong API .NET, mình có nhiều hàm bất đồng bộ gọi nối tiếp database và HTTP. Mình muốn request bị hủy thì to…
Bạn nên truyền CancellationToken từ phương thức public outermost xuống từng tác vụ con – hãy để phương thức gọi nhận một token và chuyển nó đến mọi thao tác bất đồng bộ (ví dụ: await _db.QueryAsync(... token) và await http.GetAsync(... token)). Mỗi tác vụ nội bộ nên kiểm tra token bằng cách gọi `token.ThrowIfCancellationRequested()` (hoặc sử dụng các API hỗ trợ hủy tác vụ như `await Task.Delay(...)` với token) để đảm bảo tác vụ bị hủy nhanh chóng. Đừng bao bọc OperationCanceledException trừ khi bạn cần che giấu loại lỗi này; thông thường, bạn nên để ngoại lệ lan tỏa vì nó đã mang thông tin rõ ràng về việc yêu cầu bị hủy. Nếu bạn muốn một thông báo lỗi chung, hãy bắt ngoại lệ, ghi lại nó, sau đó ném một ngoại lệ OperationCanceledException khác hoặc một loại lỗi tùy chỉnh của riêng bạn. Một mẹo nhỏ: sử dụng cùng một CancellationTokenSource cho toàn bộ chuỗi công việc để các yêu cầu hủy tác vụ có hiệu lực đồng bộ trên tất cả các bước. Điều này giúp bạn tránh được việc phải tạo nhiều nguồn hủy tác vụ riêng biệt. Bạn có đang sử dụng bất kỳ middleware logging nào để ghi lại các yêu cầu bị hủy không?
0
4. 08:50 14/10/2026
Trả lời Anh Khoa Chào admin, Trong API .NET, mình có nhiều hàm bất đồng bộ gọi nối tiếp database và HTTP. Mình muốn request bị hủy thì to…
Truyền `CancellationToken` vào **tất cả** phương thức async trong chuỗi gọi (DB context, HttpClient, thư viện bên 3) – đây là nguyên tắc "all the way down". Gọi `ThrowIfCancellationRequested()` ngay trước các điểm tốn tài nguyên (vòng lặp, query lớn, gọi HTTP) để dừng sớm, tránh lãng phí kết nối. Với `OperationCanceledException`: **không** bắt rồi ném lại exception chung (như `Exception` hay custom error 500). Hãy để nó nổi bọt lên middleware/global handler; framework sẽ tự map thành **499 Client Closed Request** (hoặc 400/500 tuỳ config) – log đủ stack trace để debug, client nhận đúng mã hủy. Lưu ý nhỏ: dùng `token.ThrowIfCancellationRequested()` thay vì `if (token.IsCancellationRequested) throw ...` để giữ stack trace sạch. Khi dùng `Task.WhenAll`, nhớ `token.Register(() => client.CancelPendingRequests())` cho HttpClient tránh leak socket. Mình hay thấy team quên cancel transaction EF Core khi request bị drop – bạn có kiểm tra `await transaction.CommitAsync(token)` hay chỉ `SaveChangesAsync(token)` thôi?
0
Vui lòng đăng nhập để tham gia trả lời chủ đề này.
Điều hướng nhanh

Bạn muốn khám phá điều gì?

Tìm chủ đề, bài viết hoặc đi thẳng đến một khu vực của cộng đồng.

Esc để đóng Ctrl K để mở lại