मैं Parallel.ForEach को कैसे सीमित कर सकता हूं?


295

मेरे पास एक Parallel.ForEach () async लूप है जिसके साथ मैं कुछ वेबपेज डाउनलोड करता हूं। मेरी बैंडविड्थ सीमित है इसलिए मैं केवल x पृष्ठ प्रति समय डाउनलोड कर सकता हूं, लेकिन Parallel.ForEach वांछित वेबपृष्ठों की पूरी सूची निष्पादित करता है।

Parallel.ForEach को चलाते समय थ्रेड नंबर या किसी अन्य सीमक को सीमित करने का कोई तरीका है?

डेमो कोड:

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

वास्तविक कार्य का वेबपृष्ठों से कोई लेना-देना नहीं है, इसलिए रचनात्मक वेब क्रॉलिंग समाधान मदद नहीं करेंगे।


@jKlaus यदि सूची को संशोधित नहीं किया गया है जैसे कि यह केवल URL का एक सेट है, तो मैं वास्तव में समस्या नहीं देख सकता हूं?
शिव

@ शिव, आपको पर्याप्त समय दिया जाएगा ... अपनी संख्या को निष्पादित करें और इसे सूची की गिनती से तुलना करें।
13:11 पर jKlaus

@jKlaus तुम क्या कह रहे हो गलत हो जाएगा?
शिव

1
@jKlaus आप एक गैर-थ्रेडसेफ़ तत्व (पूर्णांक) को संशोधित कर रहे हैं। मैं उम्मीद करूंगा कि यह उस परिदृश्य में काम नहीं करेगा। दूसरी ओर ओपी ऐसा कुछ भी संशोधित नहीं कर रहा है जिसके लिए थ्रेडसेफ़ की आवश्यकता हो।
शिव

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 है, तो समवर्ती संचालन की संख्या पर कोई सीमा नहीं है"
स्टुअर्टड

यह मेरे लिए प्रलेखन से स्पष्ट नहीं है - MaxDegreeOfParallelism को 4 पर सेट करता है (उदाहरण के लिए) इसका मतलब है कि प्रत्येक चलने वाले 1 / 4th लूप पुनरावृत्तियों के 4 धागे होंगे (4 राउंड्स में से एक भेजा), या क्या प्रत्येक थ्रेड अभी भी एक लूप करता है पुनरावृत्ति और हम सिर्फ समानांतर में कितने रन सीमित कर रहे हैं?
हाशमन

7
स्पष्ट कोर और धागे होना एक ही बात नहीं है। सीपीयू के आधार पर, प्रति कोर धागे की एक अलग संख्या होती है, आमतौर पर 2 प्रति कोर। उदाहरण के लिए, यदि आपके पास 4 कोर सीपीयू है जिसमें 2 धागे प्रति कोर हैं, तो आपके पास अधिकतम 8 धागे हैं। @JKlaus टिप्पणी समायोजित करने के लिए var opts = new ParallelOptions { MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.75) * 2.0)) };। धागों से लिंक बनाम
कोरस

41

आप समांतर सूत्र का उपयोग कर सकते हैं और समवर्ती धागों की संख्या को सीमित करने के लिए 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)  
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.