7

के अंदर रिटर्न वैल्यू और कीवर्ड समानांतर फॉरएच या लूप के लिए मान वापस करने का सही तरीका क्या है?समानांतर फॉरएच या लूप

उदाहरण के लिए निम्नलिखित कोड सही/थ्रेडसेफ है?

{ 
    Process[] processes = Process.GetProcesses(); 
    String ProcessName = String.Empty; 
    Parallel.ForEach(processes, curItem => { 
     if (curItem.Handle == this._handle) { 
      ProcessName = curItem.ProcessName; 
      return; 
     } 
    }); 
    return ProcessName; 
} 

या यह?

{ 
    Process[] processes = Process.GetProcesses(); 
    List<String> ProcessNames = new List<String>(); 
    Parallel.ForEach(processes, curItem => { 
      ProcessNames.Add(processes.ProcessName); 
     } 
    }); 
    return ProcessNames; 
} 

अन्त के लिए या foreach पाश एक समानांतर अंदर वापसी कीवर्ड के व्यवहार क्या है?

आईई: क्या यह तुरंत सभी धागे को समाप्त कर देता है? क्या इससे कोई कलाकृतियों का कारण बन सकता है जिनकी आप उम्मीद नहीं कर सकते?

उम्मीद है कि मैं जो पूछ रहा हूं वह समझ में आता है।

पीएस: अधिक विशिष्ट होने के लिए। पहला उदाहरण देखकर स्ट्रिंग थ्रेडसेफ का मेरा संशोधन है और रिटर्न स्टेटमेंट के कारण मैं जिस मूल्य की अपेक्षा करता हूं वह है? और दूसरे उदाहरण में सूची संग्रह थ्रेडसेफ का मेरा संशोधन है? क्या मेरे द्वारा अपेक्षित सभी मूल्य जोड़े जाएंगे?

उत्तर

9

मैं PLINQ यहाँ का उपयोग करेंगे:

return Process 
    .GetProcesses() 
    .AsParallel() 
    .SingleOrDefault(p => p.Handle == this._handle); 

मुझे आश्चर्य है कि क्या डेटा की मात्रा को यहाँ संभाल रहे हैं योग्यता के आधार समानांतर जा रहा ...

करने के लिए और अधिक सीधे आपके सवाल का जवाब करने के लिए, समांतर लूप से प्रारंभिक निकास को संभालें, आपको ओवरलोड में देखना चाहिए जो निष्पादन प्रतिनिधि को ParallelLoopState सौंपता है। इसका उपयोग प्रारंभिक पाश समाप्ति को नियंत्रित करने के लिए किया जा सकता है।

संपादित करें:

त्रुटियों आप देख रहे हैं, क्योंकि अपनी प्रक्रिया प्रक्रियाओं आप निरीक्षण के हत्थे का उपयोग करने के लिए पर्याप्त विशेषाधिकार नहीं है।

Process 
.GetProcesses() 
//.AsParallel() 
.Where(p=>{try{var h=p.Handle;}catch{return false;}return true;}) 
.SingleOrDefault(p => p.Handle == this._handle) 
बेशक

, यह मानते हुए this._handle वर्तमान में क्रियान्वित की प्रक्रिया के हैंडल को संदर्भित करता है:

Process.GetCurrentProcess() 

निश्चित रूप से एक बेहतर फिट होगा इस से निपटने का एक जानवर बल तरीका इस प्रकार हो सकता है?

+0

मैं इसे अवधारणा के साथ खेलने के लिए बस कर रहा हूं। मुझे लगता है कि यह शायद नहीं करता है। –

+0

क्या यह सिर्फ मुझे है? उपर्युक्त कोड निम्न त्रुटि फेंकता है: Win32Exception उपयोगकर्ता कोड द्वारा अनचाहे किया गया था। एक्सेस अस्वीकार कर दी गई है - मुझे लगता है कि हैंडल की तुलना करने के साथ इसका कुछ संबंध है? –

+0

मेरे मामले में नहीं, मेरे पास अपनी खुद की कस्टम विंडो क्लास है। यह प्रक्रिया ऑब्जेक्ट प्रदान नहीं करता कार्यक्षमता लागू करता है। मैं बस एक और एपीआई कॉल से बचने और अवधारणा के साथ खेलना चाहता था। ऐसा लगता है कि यह मानक लूप में भी काम नहीं करता है। ओह! –

6

return समानांतर फ़ोरैच लूप के अंदर मूल रूप से continue जैसा सामान्य लूप में होता है, क्योंकि return प्रत्येक आइटम के लिए निष्पादित प्रतिनिधि के अंदर होता है। इसका मतलब है, यह किसी भी धागे को समाप्त नहीं करता है और विशेष रूप से समांतर फोरैच लूप के निष्पादन को समाप्त नहीं करता है।

5

न तो सही है। आप एक मूल्य खोज रहे हैं? Parallel.ForEach यहां गलत समाधान है। आप जो खोज रहे हैं वह reduction है, जबकि ForEachmapping करता है। PLINQ का उपयोग करके समानांतर कमी का प्रदर्शन किया जा सकता है।

6

ऊपर उत्तर + के सभी:

आपको लगता है कि पाश संकेत करने के लिए बंद कर देना चाहिए चाहते हैं, आप ParallelLoopState (आप Action<T> प्रतिनिधि के बजाय Action<T, ParallelLoopState> पारित करके इस वस्तु का उपयोग कर सकते का उपयोग करना चाहिए।राज्य ऑब्जेक्ट में .Stop() या .Break() जैसी विधि है जो सिग्नल करेगा कि आप अपने लूप को निष्पादित करना बंद करना चाहते हैं (और कुछ अन्य उपयोगी गुण, इसे स्वयं से आजमाएं)।

संबंधित मुद्दे