这是关于使用 Polly 库 (v7.2.3) 和 Microsoft.Extensions.Http.Polly (v7.0.5) 的策略和上下文。我对
SetPolicyExecutionContext
类的 HttpRequestMessage
方法感到困惑:我知道当通过 HttpClientFactory 将策略添加到 HttpClient 时它会起作用,但我在 HttpClient 没有附加任何策略的情况下使用它它没有像我预期的那样工作。稍后将在策略 OnRetry 委托中使用上下文,如下所示:
OnRetry = (_, _, _, context) => {
var value = context.ContainsKey("X") ? (string)context["X"] : "NOT FOUND";
Debug.WriteLine(value);
},
使用策略的 ExecuteAsync 方法发送 HttpRequest(设置上下文后):
//Case 1 (Context in Request)
var context = new Context();
context.Add("X", "ABC");
request.SetPolicyExecutionContext(context);
policy.ExecuteAsync(() => _httpClient.SendAsync(request));
当执行此代码且 Web 请求失败时,OnRetry 处理程序始终将“NOT FOUND”写入输出。
但是如果上下文直接传递给策略,就像这样:
//Case 2 (Context in Policy)
var context = new Context();
context.Add("myKey", "ABC");
policy.ExecuteAsync((token) => _httpClient.SendAsync(request), context);
然后它按预期工作:在失败的请求上,输出得到“ABC”。
这是为什么呢?我认为在案例 1 中,ExecuteAsync 方法将从请求中获取上下文并将其传递给执行策略,因此它相当于案例 2,但这种情况并没有发生,所以看起来我错过了一些东西。
SetPolicyExecutionContext
只是执行以下:
request.Properties["PolicyExecutionContext"] = pollyContext;
这意味着在此调用之后,您可以通过
context
的 HttpRequestMessage
集合或仅通过调用 Properties
来访问 request.GetPolicyExecutionContext()
。
因此,它将上下文附加到请求对象而不是执行。
如果您想访问
OnRetry{Async}
委托内的上下文,那么您必须显式地将 context
传递给 Execute{Async}
调用。