正确实现异步重试方法 [英] Proper implementation of async retry method
问题描述
请告诉我,这种方法是否正确实现了异步模型?
Please tell me, is the asynchronous model correctly implemented in this method?
我需要实现一种方法,期望该条件得到满足,并且可能会超时.
I need to implement a method that expects the condition to be met, with the possibility of a timeout.
仅供参考:无需制定通用方法
FYI: there is no need to make a generic method
var timeout = timeout == default ? TimeSpan.FromSeconds(30) : timeout;
var stopwatch = new Stopwatch();
stopwatch.Start();
var delayTimeout = 0;
do
{
delayTimeout += 1000;
var report = await MethodAsync();
if (report.Active == true)
{
return report;
}
await Task.Delay(delayTimeout);
}
while (stopwatch.Elapsed < timeout);
throw new TimeoutException($"Timeout.");
推荐答案
重试方法可以受益于 CancellationToken
参数,因此可以随时取消.同样,如果满足超时条件,则最后一个 Task.Delay
也应省略.无需无故地将 TimeoutException
的抛出延迟额外的几秒钟.
The retry method could benefit from a CancellationToken
argument, so that is can be canceled at any moment. Also the last Task.Delay
should be omitted in case the timeout condition has been met. No need to delay the throwing of the TimeoutException
for some extra seconds without reason.
private async Task<Report> MethodWithRetryAsync(TimeSpan timeout = default,
CancellationToken cancellationToken = default)
{
timeout = timeout == default ? TimeSpan.FromSeconds(30) : timeout;
var stopwatch = Stopwatch.StartNew();
int delayTimeout = 0;
while (true)
{
var report = await MethodAsync();
if (report.Active == true) return report;
delayTimeout += 1000;
if (stopwatch.Elapsed + TimeSpan.FromMilliseconds(delayTimeout) > timeout)
{
throw new TimeoutException();
}
await Task.Delay(delayTimeout, cancellationToken);
}
}
另一个问题是,在等待 MethodAsync
的过程中发生异常时,该异常将立即传播,并且不会尝试重试.视情况而定,这是否可取.
Another issue is that in case of an exception in the awaiting of MethodAsync
, the exception will be propagated instantly and no retry will be attempted. This may be desirable or not, depending on the case at hand.
您还可以在方法中添加可选参数 maxRetries
,以允许调用方限制重试次数.同样,对 initialDelay
和 delayIncreament
进行参数化将使该方法更加灵活,以使API更加冗长为代价.
You could also add an optional argument maxRetries
to the method, to allow the caller to limit the number of retries. Also parameterizing the initialDelay
and the delayIncreament
would make the method more flexible, at the cost of making the API more verbose.
这篇关于正确实现异步重试方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!