| title | HCR021 — DelegatingHandler.SendAsync should forward the cancellation token |
|---|---|
| description | A handler that drops the incoming CancellationToken makes client disconnects and timeouts unable to cancel the outbound request. |
DelegatingHandler.SendAsync should forward the cancellation token to base.SendAsync.
SendAsync overrides receive a CancellationToken that carries client disconnects, HttpClient.Timeout, and upstream cancellation. Passing CancellationToken.None, default, or a freshly created token to base.SendAsync severs that link: the outer caller cancels, but the actual socket request keeps running — leaking connections and exhausting the thread pool under load.
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
return base.SendAsync(request, CancellationToken.None);
}Forward the token the override received:
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
return base.SendAsync(request, cancellationToken);
}When the handler needs its own timeout, link the tokens instead of discarding the caller's:
using var timeout = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
timeout.CancelAfter(TimeSpan.FromSeconds(10));
return await base.SendAsync(request, timeout.Token);The implementation reports base.SendAsync(...) invocations inside a SendAsync override on a DelegatingHandler-derived type when the token argument is CancellationToken.None, default, default(CancellationToken), or a newly constructed token — or when no token argument is passed — while the override declares a CancellationToken parameter it could forward. Overrides that forward their own parameter, a linked token, or a field token are skipped, as are overrides with no token parameter.
Suppress only when the handler intentionally detaches cancellation — for example a fire-and-forget logging handler that must outlive the caller's request. Document the reason; the default should be forwarding.