如何在 Polly ExecuteAsync 的 lambda 表达式中包含多行代码块?
How to include a multiline block of code in a lambda expression for Polly ExecuteAsync?
我有使用 Polly 策略 (IAsyncPolicy<HttpResponseMessage>
) 上的 ExecuteAsync()
方法从网页提取数据的工作代码。我想向它添加一些调试日志记录,但到目前为止我无法找出正确的语法来实现这种情况,除非我将日志记录和 http 调用包装在一个单独的方法中,然后通过 ExecuteAsync
.
这对我来说似乎不“正确”,我觉得有更简洁或更直接的方法。我认为我的问题是我对 Func<T>
和 lambda 表达式如何真正运作以实现这一点没有足够完整的理解,因为当我将内容包装在 {}
中时,我得到如下错误:
Not all code paths return a value in lambda expression of type Func<CancellationToken, Task<HttpResponseMessage>>
.
这是我原来的工作代码:
var httpClient = _httpClientFactory.CreateClient();
HttpResponseMessage result;
var retryPolicy = (IAsyncPolicy<HttpResponseMessage>)_policyRegistry[RetryPolicyKeyName];
result = await retryPolicy.ExecuteAsync(
async cancellationToken =>
await httpClient.GetAsync(myUrl, cancellationToken)
, cancellationToken
);
此代码产生“并非所有代码路径 return 类型为 Func<CancellationToken, Task>
的 lambda 表达式中的值错误:
var httpClient = _httpClientFactory.CreateClient();
HttpResponseMessage result;
var retryPolicy = (IAsyncPolicy<HttpResponseMessage>)_policyRegistry[RetryPolicyKeyName];
result = await retryPolicy.ExecuteAsync(
async cancellationToken =>
{
await httpClient.GetAsync(myUrl, cancellationToken);
}
, cancellationToken
);
这是我的“hack”,它通过额外的方法完成了我想要的事情:
private async Task<HttpResponseMessage> TestWithLogAsync(HttpClient httpClient, string myUrl, CancellationToken cancellationToken)
{
_logger.LogDebug("Requesting from: {myUrl}", myUrl);
var result = await httpClient.GetAsync(myUrl, cancellationToken);
return result;
}
var httpClient = _httpClientFactory.CreateClient();
HttpResponseMessage result;
var retryPolicy = (IAsyncPolicy<HttpResponseMessage>)_policyRegistry[RetryPolicyKeyName];
result = await retryPolicy.ExecuteAsync(
async cancellationToken =>
await TestWithLogAsync(httpClient, myUrl, cancellationToken)
, cancellationToken
);
你这里有:
result = await retryPolicy.ExecuteAsync(
await httpClient.GetAsync(managementUrl, cancellationToken)
, cancellationToken
);
相当于:
result = await retryPolicy.ExecuteAsync(async () => {
return await httpClient.GetAsync(managementUrl, cancellationToken);
}
, cancellationToken
);
因此这将在 lambda 中执行多行:
result = await retryPolicy.ExecuteAsync(async () => {
_logger.LogDebug("Requesting from: {managementUrl}", managementUrl);
return await httpClient.GetAsync(managementUrl, cancellationToken);
}
, cancellationToken
);
..虽然我不太清楚managementUrl
如何在你的例子中变成myUrl
,以及它们是否不同..我假设没有
我有使用 Polly 策略 (IAsyncPolicy<HttpResponseMessage>
) 上的 ExecuteAsync()
方法从网页提取数据的工作代码。我想向它添加一些调试日志记录,但到目前为止我无法找出正确的语法来实现这种情况,除非我将日志记录和 http 调用包装在一个单独的方法中,然后通过 ExecuteAsync
.
这对我来说似乎不“正确”,我觉得有更简洁或更直接的方法。我认为我的问题是我对 Func<T>
和 lambda 表达式如何真正运作以实现这一点没有足够完整的理解,因为当我将内容包装在 {}
中时,我得到如下错误:
Not all code paths return a value in lambda expression of type
Func<CancellationToken, Task<HttpResponseMessage>>
.
这是我原来的工作代码:
var httpClient = _httpClientFactory.CreateClient();
HttpResponseMessage result;
var retryPolicy = (IAsyncPolicy<HttpResponseMessage>)_policyRegistry[RetryPolicyKeyName];
result = await retryPolicy.ExecuteAsync(
async cancellationToken =>
await httpClient.GetAsync(myUrl, cancellationToken)
, cancellationToken
);
此代码产生“并非所有代码路径 return 类型为 Func<CancellationToken, Task>
的 lambda 表达式中的值错误:
var httpClient = _httpClientFactory.CreateClient();
HttpResponseMessage result;
var retryPolicy = (IAsyncPolicy<HttpResponseMessage>)_policyRegistry[RetryPolicyKeyName];
result = await retryPolicy.ExecuteAsync(
async cancellationToken =>
{
await httpClient.GetAsync(myUrl, cancellationToken);
}
, cancellationToken
);
这是我的“hack”,它通过额外的方法完成了我想要的事情:
private async Task<HttpResponseMessage> TestWithLogAsync(HttpClient httpClient, string myUrl, CancellationToken cancellationToken)
{
_logger.LogDebug("Requesting from: {myUrl}", myUrl);
var result = await httpClient.GetAsync(myUrl, cancellationToken);
return result;
}
var httpClient = _httpClientFactory.CreateClient();
HttpResponseMessage result;
var retryPolicy = (IAsyncPolicy<HttpResponseMessage>)_policyRegistry[RetryPolicyKeyName];
result = await retryPolicy.ExecuteAsync(
async cancellationToken =>
await TestWithLogAsync(httpClient, myUrl, cancellationToken)
, cancellationToken
);
你这里有:
result = await retryPolicy.ExecuteAsync(
await httpClient.GetAsync(managementUrl, cancellationToken)
, cancellationToken
);
相当于:
result = await retryPolicy.ExecuteAsync(async () => {
return await httpClient.GetAsync(managementUrl, cancellationToken);
}
, cancellationToken
);
因此这将在 lambda 中执行多行:
result = await retryPolicy.ExecuteAsync(async () => {
_logger.LogDebug("Requesting from: {managementUrl}", managementUrl);
return await httpClient.GetAsync(managementUrl, cancellationToken);
}
, cancellationToken
);
..虽然我不太清楚managementUrl
如何在你的例子中变成myUrl
,以及它们是否不同..我假设没有