2010-04-13 23 views
9

मैं .NET 3.5 का उपयोग कर रहा हूं और एक समस्या के आसपास अपने सिर को लपेटने की कोशिश कर रहा हूं (मेरे साथ एक सर्वोच्च थ्रेडिंग विशेषज्ञ भालू नहीं है)।सी # धागे के बीच संचार

मेरे पास एक विंडोज़ सेवा है जिसमें एक बहुत ही गहन प्रक्रिया है जो हमेशा चल रही है, मैंने इस प्रक्रिया को एक अलग थ्रेड पर रखा है ताकि मेरी सेवा का मुख्य धागा परिचालन कार्यों को संभाल सके - यानी, सेवा लेखा परीक्षा चक्र, कॉन्फ़िगरेशन को संभालना परिवर्तन, इत्यादि, आदि

मैं सामान्य थ्रेडस्टार्ट के माध्यम से थ्रेड को एक विधि में शुरू कर रहा हूं जो प्रक्रिया को बंद कर देता है - इसे कार्यकर्ताओं को कॉल करें।

इस कार्यकर्ता पर मैं अन्य सर्वर पर डेटा भेज रहा हूं, जैसा कि उम्मीद है कि सर्वर हर बार फिर से चालू हो जाता है और कनेक्शन खो जाता है और मुझे कनेक्शन को फिर से स्थापित करने की आवश्यकता होती है (मुझे किसी ईवेंट के माध्यम से कनेक्शन खोने से अधिसूचित किया जाता है)। यहां से मैं अपना पुन: कनेक्ट तर्क करता हूं और मैं वापस आ रहा हूं और दौड़ रहा हूं, हालांकि जो कुछ भी मैंने आसानी से नोटिस करना शुरू कर दिया था वह यह था कि मैं इस कार्यकर्ता धागे को हर बार बार-बार बना रहा था (जो मैं चाहता हूं)।

अब जब मैं कनेक्शन खो देता हूं और एक नया शुरू करता हूं तो यह कार्यकर्ताओं को मार सकता है लेकिन यह संसाधनों की बर्बादी की तरह लगता है।

मैं वास्तव में क्या करना चाहता हूं, मार्शल कॉल (यानी, मेरी थ्रेड स्टार्ट विधि) थ्रेड पर वापस है जो अभी भी स्मृति में है हालांकि कुछ भी नहीं कर रहा है।

कृपया आपके द्वारा उपयोग किए जाने वाले किसी भी उदाहरण या दस्तावेज़ पोस्ट करें।

धन्यवाद।

+0

क्या आप अपना कोड थोड़ा सा पोस्ट कर सकते हैं? – ChaosPandion

+1

+1 अच्छा सवाल है, लोग अब अच्छे प्रश्नों के लिए मतदान नहीं कर रहे हैं ... –

उत्तर

1

मैं वैसे भी कार्यकर्ता धागा को मार डालूंगा (लेकिन यदि संभव हो तो पूर्ण रूप से समाप्त हो)। सब कुछ कचरा इकट्ठा हो जाता है, और आप खरोंच से शुरू कर सकते हैं।

यह सर्वर रीबूट कितनी बार होता है? यदि संसाधनों के लिए अक्सर समस्या होती है, तो शायद यह अक्सर होता जा रहा है।

+0

नोट: जैसा कि dthorpe बताता है, आपको केवल थ्रेड को डंप नहीं करना चाहिए। –

1

आप सिंगलटन पैटर्न का उपयोग कर सकते हैं। अपने मामले में, कनेक्शन को स्थिर वस्तु बनाएं। दोनों थ्रेड ऑब्जेक्ट तक पहुंच सकते हैं, जिसका अर्थ यह है कि इसका निर्माण करें और इसका इस्तेमाल करें।

मुख्य थ्रेड इसे जब भी आवश्यक हो सकता है, और जब भी यह उपलब्ध हो, कार्यकर्ता थ्रेड इसे एक्सेस कर सकता है।

1

इसके बजाय ThreadPool.QueueUserWorkItem का उपयोग कर विधि को कॉल करें। यह विधि थ्रेड पूल से धागे को पकड़ती है और एक विधि को बंद कर देती है। यह किसी अन्य धागे पर एक विधि शुरू करने के कार्य के लिए आदर्श प्रतीत होता है।

इसके अलावा

, जब आप कहते हैं कि "ठेठ ThreadStart" क्या आपका मतलब आप बनाने और ThreadStart पैरामीटर के साथ एक नया Thread शुरू करने, या आप एक ThreadStart बना रहे हैं और उस पर Invoke कॉल कर रहे हैं?

+0

सामान्य रूप से धागे को उतारने से पहले जितना संभव हो उतना संसाधन साफ ​​करने का प्रयास करें, इस तरह मैं इसे अपनी विंडोज सेवा में करता हूं, लेकिन मैं पृष्ठभूमि में कई कार्यों को चलाता हूं। –

+0

@Robert: क्या आप कह रहे हैं कि 'QueueUserWorkItem' इस तरह के कभी-कभी एक-शॉट कार्य के लिए अधिक है? यह शायद सच है, लेकिन मैं इसका उपयोग करने की आदत में हूं क्योंकि मुझे पता है कि मुझे शामिल धागे का निपटान करने की चिंता करने की ज़रूरत नहीं है। – MusiGenesis

+0

QueueUserWorkItem धागे का उपयोग केवल अल्पकालिक परिचालनों के लिए किया जाना चाहिए। लंबे समय से चलने वाले संचालन के लिए थ्रेडपूल धागे का उपयोग थ्रेडपूल (धागे की सीमित संख्या) को समाप्त कर सकता है और आपकी प्रक्रिया में क्यूयूयूसर वर्कइटम के अन्य क्लाइंट्स को थ्रेडपूल थ्रेड उपलब्ध होने से पहले लंबे समय तक प्रतीक्षा करने का कारण बन सकता है। – dthorpe

1

क्या आपने BackgroundWorker माना है?

जो मैं समझता हूं उससे, आपके पास केवल एक धागा है जो काम कर रहा है, जब तक कि आवश्यकता न हो, जहां आपको cancel यह प्रसंस्करण हो।

3

आपको कार्यकर्ता धागे को मारने से बचना चाहिए। जब आप जबरन Win32 थ्रेड को मार देते हैं, तो इसके सभी संसाधन पूरी तरह से पुनर्प्राप्त नहीं होते हैं। मेरा मानना ​​है कि आरक्षित आभासी पता स्थान (या यह मूल पृष्ठ है?) थ्रेड स्टैक के लिए एक Win32 थ्रेड मारा जाता है जब पुनर्प्राप्त नहीं किया जाता है। यह बहुत अधिक नहीं हो सकता है, लेकिन एक लंबे समय से चलने वाली सर्वर सेवा प्रक्रिया में, यह समय के साथ जुड़ जाएगा और अंततः आपकी सेवा को नीचे लाएगा।

यदि धागे को सामान्य रूप से समाप्त करने के लिए अपने थ्रेडप्रोक से बाहर निकलने की अनुमति है, तो सभी संसाधन पुनर्प्राप्त किए जाते हैं।

यदि पृष्ठभूमि धागा लगातार चल रहा है (सो नहीं रहा है), तो आप मुख्य थ्रेड और पृष्ठभूमि थ्रेड के बीच राज्य को संवाद करने के लिए केवल वैश्विक बूलियन ध्वज का उपयोग कर सकते हैं। जब तक पृष्ठभूमि धागा समय-समय पर इस वैश्विक ध्वज की जांच करता है। अगर ध्वज सेट किया गया है, तो धागा साफ से नीचे बंद हो सकता है और बाहर निकल सकता है। अर्थात् लॉकिंग की आवश्यकता नहीं है यदि मुख्य धागा एकमात्र लेखक है और पृष्ठभूमि धागा केवल ध्वज मान पढ़ता है।

जब पृष्ठभूमि धागा सर्वर से कनेक्शन खो देता है कि वह डेटा भेज रहा है, तो यह अपने आप को फिर से कनेक्ट क्यों नहीं करता है? यह मुझे स्पष्ट नहीं है कि मुख्य थ्रेड को पृष्ठभूमि धागे को दूसरे को शुरू करने के लिए क्यों फाड़ना है।

1

BackgroundWorker सादे धागे का उपयोग करने से थोड़ा धीमा है, लेकिन इसमें CancelAsync विधि का समर्थन करने का विकल्प है।
असल में, BackgroundWorker कुछ अतिरिक्त विकल्प और घटनाओं के साथ एक कार्यकर्ता थ्रेड के चारों ओर एक रैपर है।

CancelAsync विधि केवल WorkerSupportsCancellation सेट होने पर ही काम करती है।
जब CancelAsync कहा जाता है, CancellationPending सेट है।
कार्यकर्ता थ्रेड को समय-समय पर छोड़ने की आवश्यकता को देखने के लिए CancellationPending की जांच करनी चाहिए।

- जेरोइन

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