Mic*_*lix 9 .net c# multithreading asynchronous
一种方法是标准的异步方法,如下所示:
private static async Task AutoRetryHandlerAsync_Worker(Func<Task<bool>> taskToRun,...)
Run Code Online (Sandbox Code Playgroud)
我测试了两个实现,一个使用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;
}
}
Run Code Online (Sandbox Code Playgroud)
而且(async t =>
使用await
而不是使用t =>
和使用.Wait()
根本不起作用,因为在return;
执行final之前不会等待递归调用的结果:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
我试图理解为什么这个简单的改变会改变一切,当它应该做同样的事情时:等待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();
}
Run Code Online (Sandbox Code Playgroud)
为什么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();
}
Run Code Online (Sandbox Code Playgroud)