【发布时间】:2019-03-10 08:31:50
【问题描述】:
我有以下异步方法,在失败的情况下更简单的等待和重试:
public async Task RetryAsync(Func<Task> _action, int _ms = 1000, int _counter = 3) {
while (true) {
try {
await _action();
return; // success!
}
catch {
if (--_counter == 0)
throw;
await Task.Delay(_ms);
}
}
}
到,理论上,这样称呼:
await RetryAsync(async () => {
_newID = myDBFunction();
}, 300);
由于传递给RetryAsync方法的函数不包含任何await,那么显然这会得到警告:
此异步方法缺少“等待”运算符,将同步运行。 考虑使用 'await' 运算符来等待非阻塞 API 调用, 或 'await Task.Run(...)' 在后台线程上执行 CPU 密集型工作。
... 并将调用代码更改为此可以解决问题:
await RetryAsync(async () => {
await Task.Run(() => _newID = myDBFunction(););
}, 300);
除了使用 Task.Run() 之外,对于这个简单的案例,还有其他方法可以实现并行性吗?您看到带有 Task.Run() 的最新代码有什么缺点吗?
【问题讨论】:
-
为什么要传递
async方法,如果实际上不是async? -
因为在大多数情况下它将是一个异步方法,它将被传递,而且我确实想实现并行性。
-
没关系,你有你的
Func<Task>签名,但实现不必是async。你可以如你所说,只使用Task.Run而不使用await和async- 那有什么问题? -
@OfirWinegarten,请写下您将如何拨打电话或如何更改重试功能。
-
我不会更改
RetryAsync,只需删除async和await。await RetryAsync(() => Task.Run(() => _newID = myDBFunction()), 300);
标签: c# asynchronous lambda async-await