ฉันจะ จำกัด Parallel.ForEach ได้อย่างไร


295

ฉันมีวงจร async Parallel.ForEach () ซึ่งฉันดาวน์โหลดบางเว็บเพจ แบนด์วิดท์ของฉันมี จำกัด ดังนั้นฉันจึงสามารถดาวน์โหลดได้เพียง x หน้าต่อครั้ง แต่ Parallel.ForEach ดำเนินการรายการทั้งหมดของเว็บเพจที่ต้องการ

มีวิธี จำกัด หมายเลขเธรดหรือตัว จำกัด อื่นใดขณะเรียกใช้ Parallel.ForEach หรือไม่

รหัสตัวอย่าง:

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

งานจริงไม่มีส่วนเกี่ยวข้องกับหน้าเว็บดังนั้นโซลูชันการรวบรวมข้อมูลบนเว็บที่สร้างสรรค์จะไม่ช่วยอะไร


@jKlaus หากไม่มีการแก้ไขรายการเช่นเป็นเพียงชุดของ URL ฉันไม่เห็นปัญหาจริงๆหรือ
ชีฟ

@Shiv ให้เวลาเพียงพอที่คุณจะ ... นับจำนวนการประหารชีวิตของคุณและเปรียบเทียบกับจำนวนของรายการ
jKlaus

@jKlaus คุณกำลังพูดอะไรจะผิดไป?
ชีฟ

1
@jKlaus คุณกำลังแก้ไของค์ประกอบที่ไม่ใช่ threadsafe (จำนวนเต็ม) ฉันคาดหวังว่ามันจะไม่ทำงานในสถานการณ์นั้น OP ในทางกลับกันไม่ได้ทำการแก้ไขสิ่งที่จำเป็นต้องเป็น threadsafe
ชีฟ

2
@jKlaus นี่คือตัวอย่างของ Parallel.ForEach ที่ชุดนับได้อย่างถูกต้อง> dotnetfiddle.net/moqP2C ลิงก์ MSDN: msdn.microsoft.com/en-us/library/dd997393(v=vs.110).aspx
jhamm

คำตอบ:


564

คุณสามารถระบุMaxDegreeOfParallelismในParallelOptionsพารามิเตอร์:

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

MSDN: Parallel.ForEach

MSDN: ParallelOptions.MaxDegreeOfParallelism


59
อาจใช้ไม่ได้กับกรณีนี้ แต่ฉันคิดว่าฉันจะทิ้งมันไปในกรณีที่มีคนสงสัยในเรื่องนี้และพบว่ามีประโยชน์ ที่นี่ฉันใช้ประโยชน์ 75% (ปัดเศษขึ้น) ของจำนวนหน่วยประมวลผล var opts = new ParallelOptions { MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.75) * 1.0)) };
jKlaus

4
เพียงบันทึกทุกคนที่ต้องค้นหาในเอกสารการส่งค่า-1เท่ากับไม่ได้ระบุเลย: "ถ้า [ค่า] -1, ไม่มีข้อ จำกัด เกี่ยวกับจำนวนของการดำเนินงานพร้อมกัน"
stuartd

มันไม่ชัดเจนสำหรับฉันจากเอกสาร - ตั้งค่า MaxDegreeOfParallelism เป็น 4 (ตัวอย่าง) หมายความว่าจะมี 4 เธรดแต่ละการรัน 1 / 4th ของการวนซ้ำวนรอบ (หนึ่งรอบของเธรดที่ส่ง 4 รอบ) หรือแต่ละเธรดยังทำหนึ่งลูป การทำซ้ำและเราแค่ จำกัด จำนวนการวิ่งขนานกัน
Hashman

7
การเป็นแกนและเธรดที่ชัดเจนนั้นไม่ใช่สิ่งเดียวกัน ขึ้นอยู่กับซีพียูมีจำนวนเธรดต่อคอร์ที่ต่างกันซึ่งมักจะเป็น 2 ต่อคอร์ ตัวอย่างเช่นหากคุณมีซีพียู 4 คอร์ที่มี 2 เธรดต่อคอร์คุณจะมีเธรดได้สูงสุด 8 เธรด var opts = new ParallelOptions { MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.75) * 2.0)) };ในการปรับความคิดเห็น @jKlaus ลิงก์ไปยังกระทู้ vs cores - askubuntu.com/questions/668538/…
TheMiddleMan

41

คุณสามารถใช้ ParallelOptions และตั้งค่า MaxDegreeOfParallelism เพื่อ จำกัด จำนวนเธรดที่เกิดขึ้นพร้อมกัน:

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

21

ใช้เกินอีกอย่างหนึ่งของParallel.Foreachที่ใช้ParallelOptionsอินสแตนซ์และชุดMaxDegreeOfParallelismที่จะ จำกัด ว่าหลายกรณีที่ดำเนินการในแบบคู่ขนาน


11

และสำหรับผู้ใช้ VB.net (ไวยากรณ์แปลกและหายาก) ...

Parallel.ForEach(listOfWebpages, New ParallelOptions() With {.MaxDegreeOfParallelism = 8}, Sub(webpage)
......end sub)  
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.