Csharp/C#教程:取消HttpClient请求 – 为什么TaskCanceledException.CancellationToken.IsCancellationRequested为false?分享


取消HttpClient请求 – 为什么TaskCanceledException.CancellationToken.IsCancellationRequested为false?

给出以下代码:

var cts = new CancellationTokenSource(); try { // get a "hot" task var task = new HttpClient().GetAsync("https://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"); } 

我希望在catch块中ex.CancellationToken.IsCancellationRequestedtrue ,但事实并非如此。 我误会了什么吗?

情况就是这样,因为HttpClient内部(在SendAsync )使用TaskCompletionSource来表示async操作。 它返回TaskCompletionSource.Task ,这是你要await的任务。

然后它调用base.SendAsync并在返回的任务上注册一个延续,相应地取消/完成/完成TaskCompletionSource的任务。

在取消的情况下,它使用TaskCompletionSource.TrySetCanceled ,它将取消的任务与新的CancellationToken相关联( default(CancellationToken) )。

您可以通过查看TaskCanceledException来查看。 在ex.CancellationToken.IsCancellationRequestedfalse ex.CancellationToken.CanBeCanceled也是false ,这意味着此CancellationToken永远不会被取消,因为它不是使用CancellationTokenSource创建的。


IMO应该使用TaskCompletionSource.TrySetCanceled(CancellationToken)代替。 这样, TaskCompletionSource将与消费者传入的CancellationToken相关联,而不仅仅是默认的CancellationToken 。 我认为这是一个错误(虽然是一个小错误),我提交了关于它的连接问题 。

上述就是C#学习教程:取消HttpClient请求 – 为什么TaskCanceledException.CancellationToken.IsCancellationRequested为false?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/956964.html

(0)
上一篇 2021年11月21日
下一篇 2021年11月21日

精彩推荐