Polly RetryForever 没有重试
Polly RetryForever isn't retrying
我正在尝试检查一个简单的 RetryForever
of Polly
class Program
{
public static void Main()
{
int i = 0;
var _retryPolicy = Policy
.Handle<Exception>()
.RetryForever();
_retryPolicy.Execute(async () =>
{
Console.WriteLine(i);
i++;
int.Parse("something");
});
Console.ReadLine();
}
}
你可以看到我创建了一个变量i
来跟踪执行次数
异常结果:
打印 i
= 0、1、2 等
实际结果:
打印 i = 0
我检查了你的代码,你是对的,它在 0 处停止。
但是当我删除 async 关键字时(你在这里没有任何异步操作)代码运行正确。
所以,试试这个:
using Polly;
int i = 0;
var _retryPolicy = Policy
.Handle<Exception>()
.RetryForever();
_retryPolicy.Execute(() =>
{
Console.WriteLine(i);
i++;
int.Parse("something");
return Task.CompletedTask;
});
我可能会迟到,但让我分享我的智慧。
当你定义一个策略时,你必须预先知道你想要修饰一个sync或一个异步 method/function.
同步方法的重试策略
Policy
.Handle<Exception>()
.RetryForever();
异步方法的重试策略
Policy
.Handle<Exception>()
.RetryForeverAsync();
- 在前一种情况下,您有一个
Execute
方法可以预期
- 一个
Action
(一个没有return值的方法)
- 或
Func<TResult>
(一种方法 TResult
输入 return 值)
- 还有许多其他重载
- 在后一种情况下,您有一个
ExecuteAsync
方法可以预期
- a
Func<Task>
(没有 return 值的异步方法)
- 或
Func<Task<TResult>>
(具有 TResult
类型 return 值的异步方法)
- 还有许多其他重载
同步功能的重试策略
Policy<int>
.Handle<Exception>()
.RetryForever();
异步函数的重试策略
Policy<int>
.Handle<Exception>()
.RetryForeverAsync();
在这些情况下,您要修饰的代码应该 return 和 int
.
因此 Execute
预期 Func<int>
代表
policy.Execute(() => { ... return 42; });
并且 ExecuteAsync
预期 Func<Task<int>>
代表
await policy.Execute(async () => { ... return Task.FromResult(42); });
返回您的代码
由于您在策略定义期间没有对 return 类型做出任何限制,因此您可以传递一个 Func
,其中 return 是一个 Task
(Execute(async () => { ...});
).
因此,您的 Execute
return 是一个 Task
,它不是 await
ed。
让我们拭目以待
await _retryPolicy.Execute(async () =>
{
Console.WriteLine(i);
i++;
int.Parse("something");
});
如果你 await
returned Task
那么它会抛出一个 FormatException
。
但是该异常是由 Execute
委托之外的 await
抛出的。因此,它将不会触发重试。
修复选项 A
_retryPolicy.Execute(() =>
{
Console.WriteLine(i);
i++;
int.Parse("something");
});
通过删除 async
,您的委托将是一个 Action
,它会抛出 FormatException
,从而触发重试策略。
修正选项 B
var _retryPolicy = Policy<int>
.Handle<Exception>()
.RetryForeverAsync();
await _retryPolicy.ExecuteAsync(async () =>
{
Console.WriteLine(i);
i++;
int.Parse("something");
});
如果您为异步方法定义了策略并且您 await
ExecuteAsync
那么它也将起作用。为什么?因为 ExecuteAsync
await
s the provided delegate 即使您没有将委托定义为 async
await _retryPolicy.ExecuteAsync(() =>
{
Console.WriteLine(i);
i++;
int.Parse("something");
return Task.CompletedTask; //This code is never reached
});
我正在尝试检查一个简单的 RetryForever
of Polly
class Program
{
public static void Main()
{
int i = 0;
var _retryPolicy = Policy
.Handle<Exception>()
.RetryForever();
_retryPolicy.Execute(async () =>
{
Console.WriteLine(i);
i++;
int.Parse("something");
});
Console.ReadLine();
}
}
你可以看到我创建了一个变量i
来跟踪执行次数
异常结果:
打印 i
= 0、1、2 等
实际结果: 打印 i = 0
我检查了你的代码,你是对的,它在 0 处停止。
但是当我删除 async 关键字时(你在这里没有任何异步操作)代码运行正确。
所以,试试这个:
using Polly;
int i = 0;
var _retryPolicy = Policy
.Handle<Exception>()
.RetryForever();
_retryPolicy.Execute(() =>
{
Console.WriteLine(i);
i++;
int.Parse("something");
return Task.CompletedTask;
});
我可能会迟到,但让我分享我的智慧。
当你定义一个策略时,你必须预先知道你想要修饰一个sync或一个异步 method/function.
同步方法的重试策略
Policy
.Handle<Exception>()
.RetryForever();
异步方法的重试策略
Policy
.Handle<Exception>()
.RetryForeverAsync();
- 在前一种情况下,您有一个
Execute
方法可以预期- 一个
Action
(一个没有return值的方法) - 或
Func<TResult>
(一种方法TResult
输入 return 值) - 还有许多其他重载
- 一个
- 在后一种情况下,您有一个
ExecuteAsync
方法可以预期- a
Func<Task>
(没有 return 值的异步方法) - 或
Func<Task<TResult>>
(具有TResult
类型 return 值的异步方法) - 还有许多其他重载
- a
同步功能的重试策略
Policy<int>
.Handle<Exception>()
.RetryForever();
异步函数的重试策略
Policy<int>
.Handle<Exception>()
.RetryForeverAsync();
在这些情况下,您要修饰的代码应该 return 和 int
.
因此 Execute
预期 Func<int>
代表
policy.Execute(() => { ... return 42; });
并且 ExecuteAsync
预期 Func<Task<int>>
代表
await policy.Execute(async () => { ... return Task.FromResult(42); });
返回您的代码
由于您在策略定义期间没有对 return 类型做出任何限制,因此您可以传递一个 Func
,其中 return 是一个 Task
(Execute(async () => { ...});
).
因此,您的 Execute
return 是一个 Task
,它不是 await
ed。
让我们拭目以待
await _retryPolicy.Execute(async () =>
{
Console.WriteLine(i);
i++;
int.Parse("something");
});
如果你 await
returned Task
那么它会抛出一个 FormatException
。
但是该异常是由 Execute
委托之外的 await
抛出的。因此,它将不会触发重试。
修复选项 A
_retryPolicy.Execute(() =>
{
Console.WriteLine(i);
i++;
int.Parse("something");
});
通过删除 async
,您的委托将是一个 Action
,它会抛出 FormatException
,从而触发重试策略。
修正选项 B
var _retryPolicy = Policy<int>
.Handle<Exception>()
.RetryForeverAsync();
await _retryPolicy.ExecuteAsync(async () =>
{
Console.WriteLine(i);
i++;
int.Parse("something");
});
如果您为异步方法定义了策略并且您 await
ExecuteAsync
那么它也将起作用。为什么?因为 ExecuteAsync
await
s the provided delegate 即使您没有将委托定义为 async
await _retryPolicy.ExecuteAsync(() =>
{
Console.WriteLine(i);
i++;
int.Parse("something");
return Task.CompletedTask; //This code is never reached
});