c# - Is Interlocked.Decrement(i) right for Parallel.ForEach()? -
अतीत में मैंने यह किया है:
सूची & gt; आइटम & gt; _Items = GetItems (); Int _CountDown = _Items.Count; (पृष्ठभूमिवर्कर _Worker = नया बैकग्राउंडवर्क ()) का उपयोग करना {_Worker.DoWork + = (s, arg) = & gt; {डोसोमिंग (_Items [_CountDown]); }; _Worker.RunWorkerCompleted + = (s, arg) = & gt; {If (System.Threading.Interlocked.Decrement (ref _CountDown) == 0) RaiseAllDoneEvent (); अन्य _Worker.RunWorkerAsync (); }; _Worker.RunWorkerAsync (); } समानांतर के साथ मैं ऐसा कुछ करना चाहता हूं: <पूर्व> सूची & gt; आइटम & gt; _Items = GetItems (); Int _CountDown = _Items.Count; System.Threading.Tasks.Parallel.ForEach (_Items, (i) = & gt; {DoSomething (i); यदि (System.Threading.Interlocked.Decrement (ref _CountDown) == 0) RaiseAllDoneEvent ();}); मेरा असली प्रश्न यह है कि इंटरलॉक किया गया है। अधिग्रहण () यहां सही है?
समानांतर। फोरेईक तब तक अवरुद्ध करे जब तक कि सभी वस्तुओं को संसाधित नहीं किया जाता है- यहां पर करने के लिए सही बात कॉलर से रैसेअले डोनइवेंट () को समानांतर कॉल करने के तुरंत बाद कॉल करने के लिए प्रतीत होती है। FOREach: < / P>
सूची & lt; आइटम & gt; _Items = GetItems (); System.Threading.Tasks.Parallel.ForEach (_Items, (i) = & gt; {DoSomething (i);}); RaiseAllDoneEvent (); दूसरे शब्दों में, नीचे गिनने की ज़रूरत नहीं है (या इस बात पर नज़र रखो कि प्रक्रिया में कितनी वस्तुएं हैं) यदि आप समानांतर संचालन को अवरुद्ध नहीं करना चाहते हैं, तो आप इसे कार्य के एक गुच्छा में बदल सकते हैं:
सूची & lt; आइटम & gt; _Items = GetItems (); कार्य। फ़ैक्टर। स्टार्टन्यू (() = & gt; {टास्क। प्रतीक्षा (सभी आइटम्स)। चयन (i = & gt; कार्य। फ़ैक्टर। स्टार्टन्यू (() = & gt; डूसममिंग (i)))। ToArray ());})। जारी रखें (t = & gt; RaiseAllDoneEvent ()); उस स्थिति में, आप स्पिन अप करने के लिए एक बाहरी कार्य शुरू करेंगे और फिर कार्य के एक गुच्छा (प्रत्येक आइटम के लिए एक) पर प्रतीक्षा करें, और फिर अंततः सभी पूर्ण घटना बढ़ाएं। इनमें से कोई भी मूल कॉलर को अवरोधित नहीं करेगा।
Comments
Post a Comment