使用 polly 并行化任务
Parallelize tasks using polly
假设我有一个类型为 List<Foo>
的对象列表 myObjs。
我有一个 polly 政策:
var policy = Policy.Handle<Exception>().RetryForever();
我想 运行 并行处理这些方法,但在每个方法失败时继续重试。
for (int i = 0; i < myObjs.Count; i++)
{
var obj = myObjs[i];
policy.Execute(() => Task.Factory.StartNew(() => obj.Do(), TaskCreationOptions.LongRunning));
}
是否会并行调用并重试每个对象?因此,如果 myObjs[5].do() 失败,是否只会重试而其他对象只执行一次?
此外,我是否应该使用接受 Func 的 ExecuteAsync() 方法而不是示例中所示的 Execute(Action) 方法? Do() 只是一个同步方法,在单独的线程中启动。
实际代码看起来像这样,其中 each() 只是一个 foreach 包装器()
_consumers.ForEach(c => policy.Execute(() => Task.Factory.StartNew(() => c.Consume(startFromBeg), TaskCreationOptions.LongRunning)));
编辑:
我试过代码:
class Foo
{
private int _i;
public Foo(int i)
{
_i = i;
}
public void Do()
{
//var rnd = new Random();
if (_i==2)
{
Console.WriteLine("err"+_i);
throw new Exception();
}
Console.WriteLine(_i);
}
}
var policy = Policy.Handle<Exception>().Retry(3);
var foos=Enumerable.Range(0, 5).Select(x => new Foo(x)).ToList();
foos.ForEach(c => policy.Execute(() => Task.Factory.StartNew(() => c.Do(), TaskCreationOptions.LongRunning)));
但得到结果:
0 1 err2 3 4 5
我以为它会重试 2 几次,但没有。知道为什么吗?
拥有任务的任何人都必须以某种方式等待它们。否则,exceptions will be ignored 并且代码将在任务实际完成之前结束。所以是的,您可能应该改用 policy.ExecuteAsync()
。它看起来像这样:
var tasks = myObjs
.Select(obj => Task.Factory.StartNew(() => obj.Do(), TaskCreationOptions.LongRunning))
.ToList();
// sometime later
await Task.WhenAll(tasks);
假设我有一个类型为 List<Foo>
的对象列表 myObjs。
我有一个 polly 政策:
var policy = Policy.Handle<Exception>().RetryForever();
我想 运行 并行处理这些方法,但在每个方法失败时继续重试。
for (int i = 0; i < myObjs.Count; i++)
{
var obj = myObjs[i];
policy.Execute(() => Task.Factory.StartNew(() => obj.Do(), TaskCreationOptions.LongRunning));
}
是否会并行调用并重试每个对象?因此,如果 myObjs[5].do() 失败,是否只会重试而其他对象只执行一次?
此外,我是否应该使用接受 Func 的 ExecuteAsync() 方法而不是示例中所示的 Execute(Action) 方法? Do() 只是一个同步方法,在单独的线程中启动。 实际代码看起来像这样,其中 each() 只是一个 foreach 包装器()
_consumers.ForEach(c => policy.Execute(() => Task.Factory.StartNew(() => c.Consume(startFromBeg), TaskCreationOptions.LongRunning)));
编辑:
我试过代码:
class Foo
{
private int _i;
public Foo(int i)
{
_i = i;
}
public void Do()
{
//var rnd = new Random();
if (_i==2)
{
Console.WriteLine("err"+_i);
throw new Exception();
}
Console.WriteLine(_i);
}
}
var policy = Policy.Handle<Exception>().Retry(3);
var foos=Enumerable.Range(0, 5).Select(x => new Foo(x)).ToList();
foos.ForEach(c => policy.Execute(() => Task.Factory.StartNew(() => c.Do(), TaskCreationOptions.LongRunning)));
但得到结果:
0 1 err2 3 4 5
我以为它会重试 2 几次,但没有。知道为什么吗?
拥有任务的任何人都必须以某种方式等待它们。否则,exceptions will be ignored 并且代码将在任务实际完成之前结束。所以是的,您可能应该改用 policy.ExecuteAsync()
。它看起来像这样:
var tasks = myObjs
.Select(obj => Task.Factory.StartNew(() => obj.Do(), TaskCreationOptions.LongRunning))
.ToList();
// sometime later
await Task.WhenAll(tasks);