Polly-调用异步ExecuteAsync(和类似方法)时,请使用异步定义的策略 [英] Polly - Please use asynchronous-defined policies when calling asynchronous ExecuteAsync (and similar) methods
问题描述
在执行包含以下内容的包装策略时,出现上述异常:重试,断路器和隔板.
I am getting the above exception when executing a wrapped policy including: retry, circuit breaker and bulk head.
我有以下政策:
var sharedBulkhead = Policy.BulkheadAsync(
maxParallelization: maxParallelizations,
maxQueuingActions: maxQueuingActions,
onBulkheadRejectedAsync: (context) =>
{
Log.Info($"Bulk head rejected => Policy Wrap: {context.PolicyWrapKey}, Policy: {context.PolicyKey}, Endpoint: {context.OperationKey}");
return TaskHelper.EmptyTask;
}
);
var retryPolicy = Policy.Handle<Exception>(e => (e is HttpRequestException)).WaitAndRetryAsync(
retryCount: maxRetryCount,
sleepDurationProvider: attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)),
onRetryAsync: (exception, calculatedWaitDuration, retryCount, context) =>
{
Log.Error($"Retry => Count: {retryCount}, Wait duration: {calculatedWaitDuration}, Policy Wrap: {context.PolicyWrapKey}, Policy: {context.PolicyKey}, Endpoint: {context.OperationKey}, Exception: {exception}.");
return TaskHelper.EmptyTask;
});
var circuitBreaker = Policy.Handle<Exception>(e => (e is HttpRequestException)).CircuitBreakerAsync(
exceptionsAllowedBeforeBreaking: maxExceptionsBeforeBreaking,
durationOfBreak: TimeSpan.FromSeconds(circuitBreakDurationSeconds),
onBreak: (exception, timespan, context) =>
{
Log.Error($"Circuit broken => Policy Wrap: {context.PolicyWrapKey}, Policy: {context.PolicyKey}, Endpoint: {context.OperationKey}, Exception: {exception}");
},
onReset: (context) =>
{
Log.Info($"Circuit reset => Policy Wrap: {context.PolicyWrapKey}, Policy: {context.PolicyKey}, Endpoint: {context.OperationKey}");
}
);
var fallbackForCircuitBreaker = Policy<bool>
.Handle<BrokenCircuitException>()
.FallbackAsync(
fallbackValue: false,
onFallbackAsync: (b, context) =>
{
Log.Error($"Operation attempted on broken circuit => Policy Wrap: {context.PolicyWrapKey}, Policy: {context.PolicyKey}, Endpoint: {context.OperationKey}");
return TaskHelper.EmptyTask;
}
);
var fallbackForAnyException = Policy<bool>
.Handle<Exception>()
.FallbackAsync(
fallbackAction: (ct, context) => { return Task.FromResult(false); },
onFallbackAsync: (e, context) =>
{
Log.Error($"An unexpected error occured => Policy Wrap: {context.PolicyWrapKey}, Policy: {context.PolicyKey}, Endpoint: {context.OperationKey}");
return TaskHelper.EmptyTask;
}
);
var resilienceStrategy = Policy.WrapAsync(retryPolicy, circuitBreaker, sharedBulkhead);
var policyWrap = fallbackForAnyException.WrapAsync(fallbackForCircuitBreaker.Wrap(resilienceStrategy));
我这样执行政策:
Task.Run(() =>
{
foreach (var changeMessage in changeMessages)
{
policyWrap.ExecuteAsync((context) => CallApi(changeMessage), new Context(endPoint));
}
});
这将产生上述异常:在调用异步ExecuteAsync(和类似方法)方法时,请使用异步定义的策略."在fallbackForAnyException
中.我在做什么错了?
This is producing the said exception: "Please use asynchronous-defined policies when calling asynchronous ExecuteAsync (and similar) methods." inside the fallbackForAnyException
. What am I doing wrong?
推荐答案
您在此处组合了同步和异步执行,因此出现了错误消息.这是由于最后一行代码:
You are combining synchronous and asynchronous execution here, hence the error message. This is because of the last line of code:
var policyWrap = fallbackForAnyException.WrapAsync(
fallbackForCircuitBreaker.Wrap(resilienceStrategy));
//^^^^
请注意我突出显示的部分.相反,应该是:
Note the bit I've highlighted. That should instead be:
var policyWrap = fallbackForAnyException.WrapAsync(
fallbackForCircuitBreaker.WrapAsync(resilienceStrategy));
这篇关于Polly-调用异步ExecuteAsync(和类似方法)时,请使用异步定义的策略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!