[英]Understanding async/await vs Wait in C# with “ContinueWith” behavior
一种方法是标准的异步方法,如下所示:
private static async Task AutoRetryHandlerAsync_Worker(Func<Task<bool>> taskToRun,...)
我测试了两个实现,一个使用await ,另一个使用.Wait()
这两个实现完全不相同,因为相同的测试失败了await版本而不是Wait() 版本 。
此方法的目标是“执行输入函数返回的任务,并通过执行相同的函数重试直到它工作”(如果达到一定次数的尝试,则自动停止的限制)。
这有效:
private static async Task AutoRetryHandlerAsync_Worker(Func<Task<bool>> taskToRun,...)
{
try {
await taskToRun();
}
catch(Exception)
{
// Execute later, and wait the result to complete
await Task.Delay(currentDelayMs).ContinueWith(t =>
{
// Wait for the recursive call to complete
AutoRetryHandlerAsync_Worker(taskToRun).Wait();
});
// Stop
return;
}
}
而这(使用async t =>
和await
而不是t =>
的使用和.Wait()
的使用根本不起作用,因为在最终return;
之前不等待递归调用的结果return;
执行:
private static async Task AutoRetryHandlerAsync_Worker(Func<Task<bool>> taskToRun,...)
{
try {
await taskToRun();
}
catch(Exception)
{
// Execute later, and wait the result to complete
await Task.Delay(currentDelayMs).ContinueWith(async t =>
{
// Wait for the recursive call to complete
await AutoRetryHandlerAsync_Worker(taskToRun);
});
// Stop
return;
}
}
我试图理解为什么这个简单的改变会改变一切,当它应该做同样的事情时:等待ContinueWith完成。
如果我提取通过ContinueWith
方法运行的任务,我确实看到ContinueWith函数的状态在内部await返回完成之前传递给“ranToCompletion”。
为什么? 是不是应该等待?
public static void Main(string[] args)
{
long o = 0;
Task.Run(async () =>
{
// #1 await
await Task.Delay(1000).ContinueWith(async t =>
{
// #2 await
await Task.Delay(1000).ContinueWith(t2 => {
o = 10;
});
});
var hello = o;
});
Task.Delay(10000).Wait();
}
为什么var hello = o;
在o = 10之前达到?
在执行可以继续之前,是不是#1等待应该挂起?
lambda语法模糊了ContinueWith( async void ...)的事实。
不等待async void方法,它们抛出的任何错误都将被忽略。
对于你的基本问题,无论如何,从捕获内重试都不是推荐的做法。 太多了,抓住块应该很简单。 并且直截了当地重试所有异常类型也是非常可疑的。 你应该知道哪些错误可以保证重试,其余的通过。
简单易懂:
while (count++ < N)
{
try
{
MainAction();
break;
}
catch(MoreSpecificException ex) { /* Log or Ignore */ }
Delay();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.