简体   繁体   中英

Parallelize tasks using polly

Let's say I have a list of objects myObjs of type List<Foo> .

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? So if myObjs[5].do() fails, will only that get retried while other objects just get executed once?

Also, am I supposed to use the ExecuteAsync() method which accepts Func<Task> instead of the Execute(Action) one as shown in the example? Do() is just a synchronous method, being launched in a separate thread. Actual code looks like this where each() is just a 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

I thought it would retry 2 a few more times, but doesn't. 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. 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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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