2016-04-14 16 views
1

Parallel.ForEach öğesinin ilk döngüsünde bir kod çalıştırmak istiyorum. Sadece ilk döngüde hangisi ise. Bunun nedeni, döngü içindeki kod tarafından üretilen diske bazı tanılama verileri yazmaktır. İlk döngüden sonra veriler sadece bellekte tutulacak ve daha sonra toplanacaktır. Bu işe yarar mı? Benim açıklamada belirtildiği gibi Parallel.ForEach öğesinin ilk döngüsü

bool firstLoop = true; 
Parallel.ForEach(someList, 
    p=> 
    { 
     // do something here 

     if (firstLoop) 
     { 
      firstLoop = false; 

      // do something here for the first loop 
     } 
    }); 
+1

Listede ilk öğe üzerinde mi yoksa yürütülen ilk döngüde mi olmalı? İterasyonların geri kalanı, bu ilk döngüde ne yapıldığına güveniyor mu? – Marc

+0

Hayır, bu kesinlikle işe yaramıyor. Burada // bir şey yapmanın gecikmesi ilkLoop'un farklı iş parçacıkları tarafından farklı noktalarda (Parallel.ForEach nedeniyle) incelenmesine ve birden çok kez güncellenmesine neden olabilir. –

+0

Özel kodunuzu, someList.Skip (1) 'üzerine paralel gitmeden önce' someList.First() 'üzerinde çalıştırmaya eğilimliydim. Basit tutun ve kendinizi bazı kötü senkronizasyon sorunları kaydedin. – spender

cevap

1

, ilk öğeyi

işleme koyuyoruz olmadığını görmek için aşağıdaki kullanabilirsiniz
if (p==items.First()) 
{ 
    //Do something 
} 

Eğer döngüler geri kalanı David tarafından önerildiği gibi bir kilit kullanabilir veya neye ihtiyacınız yapabilirsiniz sonra itimat edecektir keresinde bir şey yapmak gerekiyorsa Parallel.ForEach

Yani yapamadan

yap
//Do stuff using someList(0) 

Parallel.ForEach(someList.Skip(1), p=> 
+0

if (p == someList.First()) Bu hile gibi görünüyor. – Manngo

+0

@Manngo ile sorunu (p == someList.First()) 'neredeyse ilk döngüde yürütmeyecek, sadece listedeki ilk öğeyi içeren herhangi bir döngüde yürütecektir. –

+0

Aslında bu benim için kesinlikle yeterli. Parallel.ForEach'ın başlangıçtaki ilk X öğeleriyle başladığını varsaydım. Burada bir hobi programcısı olduğumu belirtmem gerekiyor, bu yüzden lütfen doğru açıklamayı vermediğim için beni affedin. – Manngo

1

, bu hiç çalışacağı garanti edilmez. Bir seçenek kilit oluşturmak ve sadece kilit içinde firstLoop'u değerlendirmek ve güncellemek olacaktır. Ancak bu, paralellikten bir kısmını kaybetmenize neden olacak ve işlemi tamamlamak için gereken süre boyunca baskı gereksiniminiz olmadıkça, daha iyi bir yaklaşım aramanızı öneririz. Bu, firstLoop'un listenizdeki ilk öğede değerlendirileceğini garanti etmediğini ve yalnızca bir kez doğru olarak değerlendirileceğini unutmayın. İlk öğenin üzerine ne bir şey, ve yapılıyor ne güvenmeyin tekrarlamalar geri kalanını gerekiyorsa

var someList = new List<string>(); 
var obj = new object(); 

for (int i = 0; i < 1000; i++) 
{ 
    someList.Add(i.ToString()); 
} 

bool firstLoop = true; 
var rand = new Random(Guid.NewGuid().GetHashCode()); 
Parallel.ForEach(someList, 
    p => 
    { 
     // do something here 
     var next = rand.Next(1, 100); 
     Thread.Sleep(next); 
     lock (obj) 
     { 
      if (firstLoop) 
      { 
       firstLoop = false; 
       firstLoop.Dump(); 
       // do something here for the first loop 
      } 
     } 
    });