2010-11-18 17 views
20

Özel durum işleme ve paralel görevlerle ilgili bir sorunum var.Task.WaitAll ve Özel Durumlar

Aşağıdaki kod, 2 görevi başlatır ve bitirmeleri için bekler. Benim sorunum, bir görev istisna atarsa, yakalama işleyicisine asla ulaşılamaz. Bir zaman aşımı ile görevler için beklemek için aşağıdaki kodu kullandığınızda

 List<Task> tasks = new List<Task>(); 
     try 
     {     
      tasks.Add(Task.Factory.StartNew(TaskMethod1)); 
      tasks.Add(Task.Factory.StartNew(TaskMethod2)); 

      var arr = tasks.ToArray();     
      Task.WaitAll(arr); 
     } 
     catch (AggregateException e) 
     { 
      // do something 
     } 

Ancak, özel durum yakalandı.

while(!Task.WaitAll(arr,100)); 

Ben WaitAll için belgeleri Doğru biri olmak benim ilk girişim tarif olarak, bir şeyler eksik görünüyor. Lütfen neden çalışmadığını anlamak için bana yardım edin.

+1

TaskMethod1 ve TaskMethod2 ne yapar? Hangi iş parçacığı üzerinde çalışıyorsunuz? Bunu, gerçekten yardımcı olabilecek kısa ancak * tam * bir örneğe (cevabım gibi) çevirebilirseniz. –

cevap

21

bu yeniden Can not - bu benim için çalışıyor:

using System; 
using System.Threading; 
using System.Threading.Tasks; 

class Test 
{ 
    static void Main() 
    { 
     Task t1 = Task.Factory.StartNew(() => Thread.Sleep(1000)); 
     Task t2 = Task.Factory.StartNew(() => { 
      Thread.Sleep(500); 
      throw new Exception("Oops"); 
     }); 

     try 
     { 
      Task.WaitAll(t1, t2); 
      Console.WriteLine("All done"); 
     } 
     catch (AggregateException) 
     { 
      Console.WriteLine("Something went wrong"); 
     } 
    } 
} 

baskılar ben beklediğiniz gibi "Bir şeyler ters gitti" O.

Görevlerinizden birinin bitmemiş olması mümkün mü? WaitAll, bazılarının zaten başarısız olmasına rağmen, tüm görevlerin tamamlanmasını bekler. İşte

+2

Hızlı cevabınız için teşekkürler Jon! Benim problemim/diğer görev başarısız görevine bağlıydı, bu yüzden başarısız görevde sonsuza kadar bekleyecekti. Benim fikrim şu ki, bir görev başarısız olduğunda istisna hemen yakalanıyor, bu durum böyle değil. Bunu işaret ettiğin için teşekkürler. – thumbmunkeys

+5

@pivotnig - Bağımlılığı açıkça ifade etmek için 'Görev Süreklilikleri Oluşturma' bölümüne bir göz atın - http://msdn.microsoft.com/en-us/library/dd537609.aspx –

+0

@thumbmunkeys bunun bunu yayınladığını fark etmedi. Tam olarak burada sorduğum şey: https://stackoverflow.com/q/47820918/695964 – KFL

9

(yukarıda) cevabım/soru üzerine yorumlarda ima gibi, sorunu nasıl çözdüğünü var:

arayan bariyer tarafından koordine edilen görevlerin çıkarılan her türlü özel durumları yakalar, ve diğer görevleri sinyalleri zorla iptali ile:

CancellationTokenSource cancelSignal = new CancellationTokenSource(); 
try 
{ 
    // do work 
    List<Task> workerTasks = new List<Task>(); 
    foreach (Worker w in someArray) 
    { 
     workerTasks.Add(w.DoAsyncWork(cancelSignal.Token); 
    } 
    while (!Task.WaitAll(workerTasks.ToArray(), 100, cancelSignal.Token)) ; 

} 
catch (Exception) 
{ 
    cancelSignal.Cancel(); 
    throw; 
} 
+1

Bu güzel. CancellationTokenSource' için bu kullanım durumunu asla gerçekleştiremedik. – trailmax

0

böyle bir şey çıktı bir koleksiyon her öğe için bir çağrı oluşturmaya çalışıyordum:

var parent = Task.Factory.StartNew(() => { 
    foreach (var acct in AccountList) 
    { 
     var currAcctNo = acct.Number; 
     Task.Factory.StartNew(() => 
     { 
     MyLocalList.AddRange(ProcessThisAccount(currAcctNo)); 
     }, TaskCreationOptions.AttachedToParent); 
     Thread.Sleep(50); 
    } 
    }); 

Çocuk görevinin her eklendikten sonra Thread.Sleep'ı eklemek zorunda kaldım çünkü eğer yapmazsam, işlem bir sonraki yinelemeyle currAcctNo'nun üzerine yazılır. Listemde 3 veya 4 farklı hesap numarası olurdu ve her biri işlendiğinde, ProcessThisAccount çağrısı tüm çağrılar için son hesap numarasını gösterir. Uykuyu koyduğumda, süreç harika çalışıyor.

+0

ilginizi çekebilir: http://stackoverflow.com/questions/5009181/parallel-foreach-vs-task-factory-startnew – thumbmunkeys

+0

Parallel.ForEach daha verimli? – Kiquenet

+0

Bu sorunun orijinal soruyla ne ilgisi var? burada istisna yok – knocte

İlgili konular