समानांतर तोड़ें?


111

मैं एक समानांतर से कैसे टूट सकता हूँ। लूप के लिए?

मेरे पास एक बहुत ही जटिल कथन है जो निम्नलिखित की तरह दिखता है:

Parallel.ForEach<ColorIndexHolder>(ColorIndex.AsEnumerable(),
    new Action<ColorIndexHolder>((ColorIndexHolder Element) =>
    {
        if (Element.StartIndex <= I && Element.StartIndex + Element.Length >= I)
        {
            Found = true;
            break;
        }
    }));

समानांतर वर्ग का उपयोग करते हुए, मैं इस प्रक्रिया को दूर तक अनुकूलित कर सकता हूं। तथापि; मैं समझ नहीं पा रहा हूं कि समानांतर लूप कैसे तोड़ूं? break;बयान फेंकता निम्न सिंटैक्स त्रुटि:

कोई घेरने वाला छोर, जिसमें से तोड़ना या जारी रखना है


1
क्या आप उम्मीद करेंगे कि एक ही समय में लूप के सभी समानांतर उदाहरण टूटेंगे?
n8wrl

जवाबों:


185

ParallelLoopState.Breakविधि का प्रयोग करें :

 Parallel.ForEach(list,
    (i, state) =>
    {
       state.Break();
    });

या आपके मामले में:

Parallel.ForEach<ColorIndexHolder>(ColorIndex.AsEnumerable(),
    new Action<ColorIndexHolder, ParallelLoopState>((ColorIndexHolder Element, ParallelLoopState state) =>
    {
        if (Element.StartIndex <= I && Element.StartIndex + Element.Length >= I)
        {
            Found = true;
            state.Break();
        }
    }));

बिल्कुल सही। इस बारे में खुद पोस्ट करने वाला था।
मारे इन्फिनिटस

1
एक अनुक्रमिक फॉरेस्ट लूप के बारे में सोचकर यह गारंटी दी जाती है कि आइटम से पहले आइटम जो भी कारण से ब्रेक के लिए संसाधित किया जाता है। एक समानांतर के बारे में क्या है। किसी भी वस्तु के लिए जरूरी नहीं है कि जिस क्रम में उन्हें संसाधित किया जाता है, उसका क्रम क्या है? क्या इसकी गारंटी है कि IEnumerable में सभी आइटम <...> एक के पहले जो राज्य को आमंत्रित करता है। क्रैक () संसाधित किया जा रहा है और इसके बाद आने वाले नहीं हैं? हालांकि पूर्व को किसी भी तरह हासिल किया जा सकता है, मैं नहीं देखता कि बाद में कैसे संभव होगा।
हेंड्रिक विसे

4
@ हेंड्रिक विसे: डॉक्स कहते हैं: Calling the Break method informs the for operation that iterations after the current one don't have to execute. However, all iterations before the current one will still have to be executed if they haven't already.औरthere is no guarantee that iterations after the current one will definitely not execute.
ट्यूडर

2
तो फिर state.Stop()उम्मीद के मुताबिक परिणाम प्राप्त करने के लिए अधिक उपयुक्त होगा , जैसा कि माइक पेरेनॉउड और एमबीटले द्वारा नीचे उल्लेख किया गया है
xtreampb

44

आप इसे ओवरलोड का उपयोग करके कॉल करते हैं Parallel.Forया Parallel.ForEachजो लूप अवस्था में गुजरता है, फिर कॉलिंग ParallelLoopState.Breakया ParallelLoopState.Stop। मुख्य अंतर यह है कि चीजें कितनी जल्दी टूट जाती हैं - साथ Break(), लूप वर्तमान की तुलना में पहले के "इंडेक्स" के साथ सभी वस्तुओं को संसाधित करेगा। इसके साथ Stop(), यह जितनी जल्दी हो सके बाहर निकल जाएगा।

विवरण के लिए, देखें : समानांतर या बंद लूप से कैसे रोकें या तोड़ें


3
+1, ऐसा लगता है कि हममें से कुछ के पास यहाँ ठीक वैसा ही उत्तर है :) - ओह, और मुझे आपकी टिप्पणी पर उस अन्य टिप्पणी करने वाले व्यक्ति का साथ मिला।
माइक पेरेनॉड

इस स्पष्टीकरण के लिए धन्यवाद। क्या आप जानते हैं कि जब या तो ब्रेक या स्टॉप कहा जाता है, तो क्या यह मामला है कि वर्तमान में निष्पादित पुनरावृत्तियां पूरी हो गई हैं या क्या यह निष्पादन के माध्यम से पुनरावृत्तियों को बीच में ही रोक देता है?
CeejeeB

1
@CeejeeB वर्तमान में संचालन पूर्ण कर रहा है।
रीड कोपसी

12

आपको Anyएक फ़ॉरेस्ट लूप के बजाय क्या उपयोग करना चाहिए :

bool Found = ColorIndex.AsEnumerable().AsParallel()
    .Any(Element => Element.StartIndex <= I 
      && Element.StartIndex + Element.Length >= I);

Any जल्द से जल्द रोकने के लिए पर्याप्त स्मार्ट है क्योंकि यह जानता है कि परिणाम सही होना चाहिए।


10

LoopState निश्चित रूप से एक महान जवाब है। मैंने पाया कि पिछले उत्तरों में इतना अधिक सामान था कि उत्तर को देखना मुश्किल था, इसलिए यहाँ एक सरल मामला है:

using System.Threading.Tasks;

Parallel.ForEach(SomeTable.Rows(), (row, loopState) =>
{
    if (row.Value == testValue)
    {
        loopState.Stop();  // Stop the ForEach!
    }       
    // else do some other stuff here.
});

5

बस उसी का उपयोग करें loopStateजो प्रदान किया जा सकता है।

Parallel.ForEach<ColorIndexHolder>(ColorIndex.AsEnumerable(),  
    new Action<ColorIndexHolder>((Element, loopState) => { 
        if (Element.StartIndex <= I && Element.StartIndex + Element.Length >= I) { 
            loopState.Stop();
        }     
})); 

एक उदाहरण के लिए इस MSDN लेख को देखें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.