首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用HttpClientFactory乐观地超时。如何使用取消令牌?

使用HttpClientFactory乐观地超时。如何使用取消令牌?
EN

Stack Overflow用户
提问于 2021-12-17 08:22:11
回答 1查看 542关注 0票数 -1

我想了解如何使用HttpClientFactory使用Polly实现乐观超时策略。

在网络上的示例中,调用异步方法以传递取消令牌时使用超时策略。但是,如果如导游所示,从配置服务中设置超时策略,如何管理取消令牌?

在示例代码中,在指南链接中,我看到了以下内容:

代码语言:javascript
复制
var timeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(10); // Timeout for an individual try

serviceCollection.AddHttpClient("GitHub", client =>
{
    client.BaseAddress = new Uri("https://api.github.com/");
    client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
    client.Timeout = TimeSpan.FromSeconds(60); // Overall timeout across all tries
})
.AddPolicyHandler(retryPolicy)
.AddPolicyHandler(timeoutPolicy);
EN

回答 1

Stack Overflow用户

发布于 2021-12-17 08:52:40

您应该将重试和超时策略链条为组合策略。

你有两个选择:

Wrap

代码语言:javascript
复制
.AddPolicyHandler(retryPolicy.Wrap(timeoutPolicy))
  • timeoutPolicy是内部策略,因此它适用于每一次尝试。
  • retryPolicy是外部策略,所以它是最重要的超时策略
  • 注意排序问题(我将在后面的一节中详细说明)

PolicyWrap

代码语言:javascript
复制
.AddPolicyHandler(Policy.Wrap(retryPolicy,timeoutPolicy))
  • 第一个论点是最外层的政策。
  • 最后一个论点是最内在的政策。

有序化很重要

您应该注意到,以下两种组合策略是非常不同的:

代码语言:javascript
复制
Policy.Wrap(retryPolicy,timeoutPolicy)
Policy.Wrap(timeoutPolicy, retryPolicy)
  • 在第一种情况下,有一个本地超时,它适用于每次重试尝试。
  • 在第二种情况下,您有一个全局超时,它适用于整个重试活动。

通过定义全局超时,您可以避免设置HttpClient的HttpClient属性:

代码语言:javascript
复制
var localTimeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(10);
var globalTimeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(60);
var resilientStrategy = Policy.Wrap(globalTimeoutPolicy, retryPolicy, localTimeoutPolicy);

serviceCollection.AddHttpClient("GitHub", client =>
{
    client.BaseAddress = new Uri("https://api.github.com/");
    client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
})
.AddPolicyHandler(resilientStrategy);

更新#1乐观超时

Polly的超时确实支持乐观悲观超时。换句话说,Polly可以尝试取消那些预期到CancellationToken (乐观)的包装方法,以及那些不悲观的方法。默认情况是前者。

在乐观的情况下,您有两个选择:

  • 让保险单取消
代码语言:javascript
复制
await policy.ExecuteAsync(
   async ct => await httpClient.SendAsync(..., ct),
   CancellationToken.None);
  • 或将其与您的自定义CTS结合/链接
代码语言:javascript
复制
await policy.ExecuteAsync(
   async ct => await httpClient.SendAsync(..., ct),
   cancellationSource.Token);

如果在启动期间注册了命名/类型化客户端,则只能使用第一个选项。因为policy.ExecuteAsync将代表您(隐式)调用。

如果您注册了一个类型化的客户机,并且在该客户机中定义了策略,那么您将对ExecuteAsync进行显式调用,在那里您可以决定使用哪个版本。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70390221

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档