2010-03-22 6 views
7

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

//spawn a thread to handle the processing of pdf on each folder. 
       var th = new Thread(() => 
       { 
        pdfDirectories = Directory.GetDirectories(pdfPath); 
        processDir(pdfDirectories); 
       }); 
       th.Start(); 



private void processDir(string[] dirs) 
     { 
      foreach (var dir in dirs) 
      { 
       pdfFiles = Directory.GetFiles(dir, "*.pdf"); 
       processFiles(pdfFiles); 

       string[] newdir = Directory.GetDirectories(dir); 
       processDir(newdir); 
      } 
     } 



private void processFiles(string[] files) 
     { 
      foreach (var pdf in files) 
      { 
       ThreadPoolHelper.QueueUserWorkItem(
        new { path = pdf }, 
        (data) => { processPDF(data.path); } 
        ); 
      } 
     } 

मेरे समस्या है, मैं कैसे पता है कि थ्रेड पूल के धागे सभी कतारबद्ध आइटम प्रसंस्करण तो मैं कि आवेदन अपने उद्देश्य कार्य के साथ किया जाता है उपयोगकर्ता बता सकते हैं समाप्त हो गया है करते हैं?

उत्तर

4

आम तौर पर मैं काउंटर वैरिएबल होने से ऐसा कुछ करूंगा। प्रत्येक कार्य आइटम के लिए आप ThreadPool में कतार में काउंटर वैरिएबल में जोड़ें। फिर जब इसे संसाधित किया जाता है तो आप काउंटर वैरिएबल को कम कर देंगे।

सुनिश्चित करें कि आप Interlocked कक्षा पर विधियों के माध्यम से वृद्धि और कमी कर रहे हैं क्योंकि यह सुनिश्चित करेगा कि चीजें थ्रेड-सुरक्षित तरीके से की जाती हैं।

एक बार काउंटर हिट शून्य आप झंडा कि कार्य एक ManualResetEvent

का उपयोग कर आप .NET 4 के लिए उपयोग किया है, तो आप एक ऐसी ही बात करने के लिए नई CountdownEvent वर्ग का उपयोग कर सकते पूरा कर रहे हैं सकता है।

+0

मैंने इस तरह के एक समान तर्क किया है। केवल मैंने थ्रेडपूल का उपयोग किया। GetAvailableThreads। मैंने मैक्स थ्रेड को सेट किया है, पूल को 20 तक इस्तेमाल किया जाना चाहिए। इसलिए आखिरी कार्य में मैंने जांच की कि क्या उपलब्ध धागे अधिकतम सेट के बराबर हैं। दुर्भाग्य से यह विफल रहता है। मैं उस मैनुअल रीसेट इवेंट पर शोध करूंगा। –

+1

@mcxiand: आप थ्रेडपूल काउंटर का उपयोग नहीं कर सकते क्योंकि अन्य कोड (lib) थ्रेड बना सकता है और टीपी उन्हें रीसाइक्लिंग/हटा रहा है। –

+0

@ हेनक होल्टरमैन: क्या ऐसा है? जो मैंने समझा वह है कि, ThreadPool QueueUserWorkItem विधि द्वारा कार्य की कतारबद्ध होगी। क्या आप अपनी टिप्पणी के बारे में अधिक जानकारी दे सकते हैं? इसकी बहुत सराहना की जाएगी। –

2

1) कैसे पता चलेगा कि सभी धागे समाप्त हो गए हैं? यह आपकी गुमनाम प्रतिनिधियों को खराब करता बहुत ज्यादा तो बस आवरण तरीकों का उपयोग करते हैं

Interlocked.Increment(ref jobCounter); 
// your code 
Interlocked.Decrement(ref jobCounter); 

:

आप धागे, अपने स्वयं के चेक-इन/चेक-आउट करते हैं करने के लिए के बीच अपने कोड bracketing से होगा। आपको शायद अपवाद हैंडलिंग भी जोड़नी होगी।

इंटरलाक्ड दृष्टिकोण अभी भी 0 बनने की प्रतीक्षा करने की समस्या को बचाता है, नींद के साथ एक लूप एक कमजोर है लेकिन इस मामले में व्यावहारिक समाधान है।

2) आप एक रिकर्सिव ट्री वॉकर में धागे शुरू कर रहे हैं। सावधान रहें, आप शायद उनमें से अधिकतर बना रहे हैं और इससे प्रदर्शन को नुकसान पहुंचाएगा।

+0

मेरे पास थ्रेड –

+0

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

+0

मैंने मैक्स थ्रेड को नियंत्रित किया क्योंकि इस धागे पर, मैं BeginInvoke का उपयोग कर यूआई नियंत्रण अपडेट कर रहा हूं। यदि बहुत सारे थ्रेड चल रहे हैं तो यूआई स्थिर हो जाएगा। कोई सिफारिशें? –