Ответ 1
В этом случае, поскольку HttpClient
внутри (в SendAsync
) использует TaskCompletionSource
для представления операции async
. Он возвращает TaskCompletionSource.Task
и что задача await
включена.
Затем он вызывает base.SendAsync
и регистрирует продолжение в возвращаемой задаче, которая соответственно отменяет/завершает/вызывает задачу TaskCompletionSource
.
В случае отмены используется TaskCompletionSource.TrySetCanceled
, который связывает отмененную задачу с новым CancellationToken
(default(CancellationToken)
).
Это можно увидеть, посмотрев на TaskCanceledException
. В верхней части ex.CancellationToken.IsCancellationRequested
находится false
ex.CancellationToken.CanBeCanceled
также false
, что означает, что этот CancellationToken
никогда нельзя отменить, поскольку он не был создан с помощью CancellationTokenSource
.
IMO следует использовать TaskCompletionSource.TrySetCanceled(CancellationToken)
. Таким образом, TaskCompletionSource
будет связан с CancellationToken
, переданным потребителем, а не просто по умолчанию CancellationToken
. Я думаю, что это ошибка (хотя и небольшая), и я отправил вопрос о подключении об этом.