简体   繁体   English

使用 polly 并行化任务

[英]Parallelize tasks using polly

Let's say I have a list of objects myObjs of type List<Foo> .假设我有一个List<Foo>类型的对象myObjs列表。

I have a polly policy:我有一个波利政策:

var policy = Policy.Handle<Exception>().RetryForever();

which i want to run methods on in parralel, but keep retrying each as they fail.我想在并行中运行方法,但在它们失败时继续重试。

for (int i = 0; i < myObjs.Count; i++)
{
  var obj = myObjs[i];
  policy.Execute(() => Task.Factory.StartNew(() => obj.Do(), TaskCreationOptions.LongRunning));
}

Will this be called in parallel and retry each obj?这会被并行调用并重试每个obj吗? So if myObjs[5].do() fails, will only that get retried while other objects just get executed once?因此,如果myObjs[5].do()失败,是否只会重试其他对象,而其他对象只会执行一次?

Also, am I supposed to use the ExecuteAsync() method which accepts Func<Task> instead of the Execute(Action) one as shown in the example?另外,我是否应该使用接受Func<Task>ExecuteAsync()方法,而不是示例中所示的Execute(Action)方法? Do() is just a synchronous method, being launched in a separate thread. Do()只是一个同步方法,在单独的线程中启动。 Actual code looks like this where each() is just a foreach wrapper()实际代码如下所示,其中each()只是一个 foreach wrapper()

_consumers.ForEach(c => policy.Execute(() => Task.Factory.StartNew(() => c.Consume(startFromBeg), TaskCreationOptions.LongRunning)));

EDIT:编辑:

I tried the code:我试过代码:

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)));

but am getting result:但我得到了结果:

0 1 err2 3 4 5 0 1 错误 2 3 4 5

I thought it would retry 2 a few more times, but doesn't.我以为它会再重试2次,但没有。 Any idea why?知道为什么吗?

Whatever owns the tasks must wait for them somehow.任何拥有这些任务的人都必须以某种方式等待它们。 Otherwise, exceptions will be ignored and the code will end before the tasks actually complete.否则, 异常将被忽略,代码将在任务实际完成之前结束。 So yes, you should probably be using policy.ExecuteAsync() instead.所以是的,您可能应该改用policy.ExecuteAsync() It would look something like this:它看起来像这样:

var tasks = myObjs
    .Select(obj => Task.Factory.StartNew(() => obj.Do(), TaskCreationOptions.LongRunning))
    .ToList();

// sometime later
await Task.WhenAll(tasks);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM