Parallel.ForEach'ı nasıl sınırlayabilirim?


296

Bazı web sayfalarını indirdiğim bir Parallel.ForEach () zaman uyumsuz döngüsü var. Bant genişliğim sınırlıdır, bu yüzden her seferinde yalnızca x sayfa indirebilirim ancak Parallel.ForEach istenen web sayfalarının listesini yürütür.

Parallel.ForEach çalıştırılırken iplik numarasını veya başka bir sınırlayıcıyı sınırlamanın bir yolu var mı?

Demo kodu:

Parallel.ForEach(listOfWebpages, webpage => {
  Download(webpage);
});

Gerçek görevin web sayfalarıyla hiçbir ilgisi yoktur, bu nedenle yaratıcı web tarama çözümleri yardımcı olmaz.


@jKlaus Liste değiştirilmediyse, örneğin yalnızca bir URL kümesiyse, sorunu gerçekten göremiyorum?
Shiv

@Shiv, yeterince zaman verdiğinizde ... İnfaz sayınızı ve listenin sayımıyla karşılaştırın.
jKlaus

@jKlaus Ne yanlış gideceğini söylüyorsun?
Shiv

1
@jKlaus, iş parçacığı olmayan bir öğeyi (tamsayı) değiştiriyorsunuz. Bu senaryoda çalışmamasını beklerdim. Öte yandan OP, güvenli olması gereken hiçbir şeyi değiştirmiyor.
Shiv

2
@jKlaus Sayıyı doğru ayarlayan bir Parallel.ForEach örneği> dotnetfiddle.net/moqP2C . MSDN Bağlantısı: msdn.microsoft.com/en-us/library/dd997393(v=vs.110).aspx
jhamm

Yanıtlar:


565

MaxDegreeOfParallelismBir ParallelOptionsparametrede a belirtebilirsiniz :

Parallel.ForEach(
    listOfWebpages,
    new ParallelOptions { MaxDegreeOfParallelism = 4 },
    webpage => { Download(webpage); }
);

MSDN: Parallel.ForEach

MSDN: ParallelOptions.MaxDegreeOfParallelism


59
Bu özel durum için geçerli olmayabilir, ancak herkesin bu konuda harikalar yaratması ve faydalı bulması durumunda atmam gerektiğini düşündüm. Burada işlemci sayısının% 75'ini (yuvarlanmış) kullanıyorum. var opts = new ParallelOptions { MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.75) * 1.0)) };
jKlaus

4
Belgede aramak zorunda olan başka birini kaydetmek için, değerini geçmek -1hiç belirtmemekle aynıdır: "[değer] -1 ise, eşzamanlı olarak çalışan işlemlerin sayısında bir sınır yoktur"
stuartd

Belgelerden bana açık değil - MaxDegreeOfParallelism'i 4'e ayarlamak (örneğin), her biri döngü yinelemelerinin 1 / 4'ünü (gönderilen 4 iş parçacığından bir tur) çalışan 4 iş parçacığı olacağı veya her iş parçacığının yine de bir döngü yaptığı anlamına gelir yineleme ve kaç paralel koşuyoruz?
Hashman

7
Açık olmak gerekirse, çekirdekler ve iplikler aynı şey değildir. CPU'ya bağlı olarak, çekirdek başına genellikle çekirdek başına 2 olmak üzere farklı sayıda iş parçacığı vardır. Örneğin, çekirdek başına 2 iş parçacığı olan 4 çekirdekli bir CPU'nuz varsa, maksimum 8 iş parçacığınız vardır. @JKlaus yorumunu ayarlamak için var opts = new ParallelOptions { MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.75) * 2.0)) };. Konulara
TheMiddleMan

41

ParallelOptions'ı kullanabilir ve eşzamanlı iş parçacığı sayısını sınırlamak için MaxDegreeOfParallelism'i ayarlayabilirsiniz:

Parallel.ForEach(
    listOfwebpages, 
    new ParallelOptions{MaxDegreeOfParallelism=2}, 
    webpage => {Download(webpage);});     

21

Bunun Parallel.Foreachbir ParallelOptionsörneğini alması için başka bir aşırı yükleme kullanın ve MaxDegreeOfParallelismkaç eşgörünümün paralel olarak yürütüleceğini sınırlamaya ayarlayın .


11

Ve VB.net kullanıcıları için (sözdizimi garip ve bulmak zor) ...

Parallel.ForEach(listOfWebpages, New ParallelOptions() With {.MaxDegreeOfParallelism = 8}, Sub(webpage)
......end sub)  
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.