2010-01-19 9 views
7

में अधिकतम पंक्तिबद्ध तत्व मैंने अधिकतम धागा 10 पर सेट किया। फिर मैंने ThreadPool.QueueUserWorkItem का उपयोग करके 22000 कार्य जोड़ा। यह बहुत संभावना है कि कार्यक्रम चलाने के बाद सभी 22000 कार्य पूरा नहीं हुआ। क्या कोई सीमा है कि उपलब्ध धागे के लिए कितने कार्य कतारबद्ध किए जा सकते हैं?ThreadPool.QueueUserWorkItem

उत्तर

6

कतार में कोई व्यावहारिक सीमा नहीं है हालांकि पूल स्वयं 64 प्रतीक्षा हैंडल से अधिक नहीं होगा, यानी कुल धागे सक्रिय हैं।

+0

एक बग ने मेरी समस्या का कारण बना दिया, लेकिन मूल रूप से सवाल का जवाब यह है। –

+0

धन्यवाद @किथ। तो ऐसा लगता है कि कतार आकार की एकमात्र असली सीमा एक सामान्य कतार (या समान) ऑब्जेक्ट का आकार है। – matrixugly

+0

क्या? मेरे पास 150 थ्रेड पूल धागे सक्रिय हैं! – Vlad

4

documentation of ThreadPool से:

नोट: कामयाब थ्रेड पूल में धागे पृष्ठभूमि धागे हैं। यही है, उनके IsBackground गुण सत्य हैं। इसका मतलब है कि एक थ्रेडपूल थ्रेड सभी अग्रभूमि धागे से बाहर निकलने के बाद चल रहे एप्लिकेशन को नहीं रखेगा।

क्या यह संभव है कि आप सभी कार्यों को संसाधित करने से पहले बाहर निकल रहे हों?

4

यह एक कार्यान्वयन निर्भर प्रश्न है और इस समारोह के कार्यान्वयन में थोड़ा सा समय बदल गया है। लेकिन .NET 4.0 में, आप सिस्टम में स्मृति की मात्रा से अनिवार्य रूप से सीमित हैं क्योंकि कार्यों को मेमोरी कतार में संग्रहीत किया जाता है। आप इसे परावर्तक में कार्यान्वयन के माध्यम से खोदकर देख सकते हैं।

11

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

यह स्थिति इस प्रकार की संभाल करने के लिए एक अपेक्षाकृत स्वच्छ तरीका है:

using (var mre = new ManualResetEvent(false)) 
{ 
     int remainingToProcess = workItems.Count(); // Assuming workItems is a collection of "tasks" 
     foreach(var item in workItems) 
     { 
      // Delegate closure (in C# 4 and earlier) below will 
      // capture a reference to 'item', resulting in 
      // the incorrect item sent to ProcessTask each iteration. Use a local copy 
      // of the 'item' variable instead. 
      // C# 5/VS2012 will not require the local here. 
      var localItem = item; 
      ThreadPool.QueueUserWorkItem(delegate 
      { 
       // Replace this with your "work" 
       ProcessTask(localItem); 

       // This will (safely) decrement the remaining count, and allow the main thread to continue when we're done 
       if (Interlocked.Decrement(ref remainingToProcess) == 0) 
         mre.Set(); 
      }); 
     } 
     mre.WaitOne(); 
} 

कहा जा रहा है, यह आमतौर पर करने के लिए "समूह" एक साथ अपने काम आइटम बेहतर है आप उनमें से हजारों है, और थ्रेडपूल के लिए उन्हें अलग-अलग कार्य आइटम के रूप में नहीं मानें। यह आइटम की सूची प्रबंधित करने में शामिल कुछ ओवरहेड है, और चूंकि आप एक समय में 22000 को संसाधित नहीं कर पाएंगे, इसलिए आप इन्हें ब्लॉक में समूहित करने से बेहतर हैं। एकल कार्य आइटम होने से प्रत्येक प्रक्रिया 50 या इससे भी अधिक संभवतः आपके समग्र थ्रूपुट को थोड़ा सा मदद मिलेगी ...

+0

अच्छा विचार है, लेकिन ऐप सभी धागे के लिए इंतजार कर रहा था। ग्रुपिंग भी एक बहुत अच्छा सुझाव है। –

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