Tod*_*ier 30 .net c# async-await cancellationtokensource dotnet-httpclient
给出以下代码:
var cts = new CancellationTokenSource();
try
{
// get a "hot" task
var task = new HttpClient().GetAsync("http://www.google.com", cts.Token);
// request cancellation
cts.Cancel();
await task;
// pass:
Assert.Fail("expected TaskCanceledException to be thrown");
}
catch (TaskCanceledException ex)
{
// pass:
Assert.IsTrue(cts.Token.IsCancellationRequested,
"expected cancellation requested on original token");
// fail:
Assert.IsTrue(ex.CancellationToken.IsCancellationRequested,
"expected cancellation requested on token attached to exception");
}
Run Code Online (Sandbox Code Playgroud)
我希望ex.CancellationToken.IsCancellationRequested
是true
在catch块内,但事实并非如此.我误会了什么吗?
i3a*_*non 43
情况就是这样,因为HttpClient
内部(in SendAsync
)使用a TaskCompletionSource
来表示async
操作.它返回TaskCompletionSource.Task
,这是你的任务await
.
然后base.SendAsync
,它会在返回的任务上调用并注册一个延续,从而相应地取消/完成/排除TaskCompletionSource
任务.
在取消的情况下,它使用TaskCompletionSource.TrySetCanceled
将取消的任务与new CancellationToken
(default(CancellationToken)
)相关联.
你可以通过查看来看到TaskCanceledException
.在顶部ex.CancellationToken.IsCancellationRequested
的存在false
ex.CancellationToken.CanBeCanceled
也是false
,这意味着这CancellationToken
因为它不使用创建不能被取消CancellationTokenSource
.
IMO应该使用它TaskCompletionSource.TrySetCanceled(CancellationToken)
.这样,TaskCompletionSource
它将与CancellationToken
消费者传入而不仅仅是默认值相关联CancellationToken
.我认为这是一个错误(虽然是一个小错误),我提交了关于它的连接问题.