【问题标题】:.NET C# : HttpClient and the TaskCanceledException exception.NET C#:HttpClient 和 TaskCanceledException 异常
【发布时间】:2023-04-09 18:39:01
【问题描述】:

我已经开始使用 System.Net.Http.HttpClient,这是一个很棒的课程。我现在想让我的程序的用户能够取消操作,例如,如果一堆 HTTP 请求需要很长时间才能完成。因此,很自然地,我遇到了 CancellationTokenSource 类,并修改了我对 HttpClient 的异步方法的调用,以便也将 CancellationToken 传递给它们。在我的 UI 代码中,我现在可以“取消该令牌”,实际上它会中断当时正在进行的任何 HTTP 请求。

然而,我没想到的是,这会导致被中断的方法抛出 TaskCanceledException 异常。

这是我的问题:我查看了 HttpClient 的 MSDN 文档,但没有发现该异常。我想这是因为它是任何采用 CancellationToken 的异步方法的常见行为,但到目前为止我还没有找到太多关于此的信息。您能否证实或证实我的假设,并指出相关文件?

我的“真正问题”是我是否正确使用了 CancellationToken 机制,意思是应该发生该异常,还是我做错了什么?

如果该异常应该发生,并且如果它是我可以依赖的机制,那么它将简化我的代码。现在,我在每次调用 HttpClient 异步方法后测试我的令牌的 IsCancellationRequested 属性,以确定我的方法应该继续还是返回,但是除了这个例外,所有额外的代码都变成了毫无意义。

我正在使用此语句取消令牌:

myCancellationTokenSource.Cancel();

【问题讨论】:

  • 当您问“我这样做是否正确”时,请使用代码而不是文字来解释您当前正在做什么。代码跨越所有语言障碍。
  • 这是为了抛出异常。
  • Scott,我同意你的观点,但我没有做任何特别的事情(没有双关语)。我会看看我能做什么。
  • John :这就是我所相信的,但我想 100% 确定,因此我要求提供文档。我不能仅仅根据某人告诉我“它应该这样做”来做出软件设计决定,我相信你明白。

标签: c# .net exception async-await dotnet-httpclient


【解决方案1】:

Is catching TaskCanceledException and checking Task.Canceled a good idea?

在.Net 框架本身中,当您将CancellationToken 作为参数传递时,您将返回TaskCanceledException。我不会违背这一点并创建自己的设计模式,因为熟悉 .Net 的人会熟悉您的代码。

我的指导方针是:取消令牌的是应该处理 TaskCanceledException 的那个,所以如果您出于自己的原因在方法中使用 CancellationToken,请继续使用 @987654330 @ 堵塞。 但是如果获取token作为参数,就让异常抛出

https://blogs.msdn.microsoft.com/andrewarnottms/2014/03/19/recommended-patterns-for-cancellationtoken/

在你完成工作后不要抛出 OperationCanceledException,仅仅因为令牌被发出信号。返回一个成功的结果,让调用者决定下一步做什么。调用者无论如何都不能假设您在给定的时间点可以取消,因此即使取消,他们也必须为成功的结果做好准备。

在我看来,cancellationToken.ThrowIfCancellationRequested() 是处理与 cancelToken 的大多数交互的最简单方法。那么你只需要处理异常。

【讨论】:

  • 我认为我们意见一致。您是否有任何关于 TaskCancelledException 的 MSDN 链接,因为它与 HttpClient 相关?
  • 我不确定他们是否记录了他们认为是标准的东西……不过,您总是可以从源头中挖掘。例如。 github.com/dotnet/corefx/blob/…
【解决方案2】:

在取消时抛出 TaskCanceledException 是所有接受 CancellationToken 参数的方法的规范。这并不总是被记录在案是(IMO)疏忽。

但至少有一些关于整体模式的文档,以记录一般意义上的行为:

https://docs.microsoft.com/en-us/dotnet/standard/threading/cancellation-in-managed-threads

https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-cancellation

https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-cancel-a-task-and-its-children

文档有时也只是提到 OperationCanceledException 来暗示 TaskCanceledException,因为它们是超类和子类。

【讨论】:

    猜你喜欢
    • 2019-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多