2016-10-24 2 views
1

Предположим, у меня есть список объектов myObjs типа List<Foo>.Параллелизировать задачи с использованием polly

У меня есть политика Polly:

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

, который я хочу, чтобы запустить методы в parralel, но продолжать соединяться друг, как они терпят неудачу.

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

Будет ли это вызываться параллельно и повторять каждый объект? Итак, если myObjs [5] .do() не удастся, будет ли он повторен только в том случае, если другие объекты просто выполняются один раз?

Также я должен использовать метод ExecuteAsync(), который принимает Func вместо Execute (Action), как показано в примере? Do() - это просто синхронный метод, который запускается в отдельном потоке. Фактический код выглядит следующим образом, где каждый() просто Еогеасп обертка()

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

EDIT:

Я попробовал код:

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

Я думал, что повторю еще пару раз, но это не так. Любая идея почему?

ответ

1

Независимо от того, что принадлежит задачам, они должны как-то подождать. В противном случае, 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); 
+0

Да, это работает сейчас. Я использовал Task.WhenAll (задачи) .GetAwaiter(). GetResult(); в моем методе синхронизации и в используемой версии RetryAsync(). – arviman

Смежные вопросы