Khai báo tham số CancellationToken ở action hoặc minimal API endpoint thì model binding tự gán HttpContext.RequestAborted — token này bị huỷ khi client ngắt kết nối (đóng tab, timeout, huỷ request).
[HttpGet("reports")]
public async Task<IActionResult> GetReport(CancellationToken ct)
{
var rows = await _db.Orders.Where(o => o.IsPaid).ToListAsync(ct);
var res = await _http.GetAsync("https://api.partner.vn/rate", ct);
return Ok(rows);
}Nguyên tắc: truyền token xuống tận đáy — EF Core (ToListAsync(ct)), HttpClient, Redis, file I/O. Nếu chỉ nhận rồi bỏ đó thì user huỷ request nhưng server vẫn chạy hết query nặng, tốn kết nối DB vô ích.
Cần ghép thêm timeout của riêng service thì tạo linked token:
using var cts = CancellationTokenSource.CreateLinkedTokenSource(ct);
cts.CancelAfter(TimeSpan.FromSeconds(5));
var data = await _slowApi.FetchAsync(cts.Token);Hai lưu ý khi vận hành:
- Khi bị huỷ, lời gọi ném OperationCanceledException. Đừng log nó ở mức Error — client huỷ là chuyện bình thường, log Error sẽ làm nhiễu cảnh báo.
- Không truyền request token vào công việc phải hoàn tất (ghi audit log, publish message sau khi commit) — client ngắt kết nối sẽ cắt ngang giữa chừng.