2012-03-07 11 views
8

मेरे पास एक विधि है void DoWork(object input) जो पूरा होने में लगभग 5 सेकंड लगते हैं। मैंने पढ़ा है कि Thread इन लंबे परिचालनों के लिए ThreadPool से बेहतर अनुकूल है लेकिन मुझे एक समस्या आई है।थ्रेड: एक बार पूरा होने के बाद थ्रेड को फिर से शुरू कैसे करें?

मैं एक बटन क्लिक करता हूं जो threadRun.Start(input) पर कॉल करता है जो ठीक चलता है और पूरा करता है। मैं फिर से बटन पर क्लिक करें और निम्न अपवाद प्राप्त करते हैं:

Thread is running or terminated; it cannot restart.

आप नहीं एक थ्रेड "पुन: उपयोग" कर सकते हैं? क्या मुझे थ्रेडपूल का उपयोग करना चाहिए? ThreadPool की तुलना में थ्रेड "लंबे संचालन के लिए बेहतर अनुकूल" क्यों है? यदि आप धागे का पुन: उपयोग नहीं कर सकते हैं, तो इसका उपयोग क्यों करें (यानी यह क्या फायदे हैं)?

+0

मैंने अभी कुछ कोड चेक किया है और मैं हर बार थ्रेड को फिर से बना देता हूं मुझे इसका पुन: उपयोग करने की ज़रूरत है। मैंने ऐसा इसलिए किया क्योंकि मुझे भी मेरे कोड में एक ही त्रुटि मिल रही थी। मेरे मामले में ऐसा करने के लिए यह बहुत महंगा नहीं था इसलिए मैंने आगे की जांच नहीं की। – ChrisF

+0

ThreadPool बनाम धागा के लिए यह [stackoverflow पोस्ट] जाँच [1] [1]: http://stackoverflow.com/questions/230003/thread-vs-threadpool –

उत्तर

10

क्या आप थ्रेड का पुन: उपयोग नहीं कर सकते?

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

क्या मुझे थ्रेडपूल का उपयोग करना चाहिए?

यदि आप थ्रेड का पुनः उपयोग करना चाहते हैं, तो हाँ।

थ्रेडपूल की तुलना में थ्रेड "लंबे संचालन के लिए बेहतर अनुकूल" क्यों है?

एक थ्रेड पूल की कल्पना करें जो बड़ी संख्या में त्वरित संचालन की सेवा कर रहा है। आप बहुत सारे धागे नहीं लेना चाहते हैं, क्योंकि कंप्यूटर एक समय में केवल इतना ही काम कर सकता है। प्रत्येक लंबे ऑपरेशन से आप थ्रेड पूल पूल से धागे को जोड़ते हैं। तो पूल में या तो बहुत सारे अतिरिक्त धागे हैं या धागे से कम चल सकते हैं। न तो एक कुशल थ्रेड पूल डिजाइन की ओर जाता है।

लंबे परिचालनों के लिए, ऑपरेशन की लागत की तुलना में थ्रेड बनाने और नष्ट करने का ओवरहेड बहुत छोटा है। तो ऑपरेशन के लिए सिर्फ धागे का उपयोग करने का सामान्य नकारात्मक प्रभाव लागू नहीं होता है।

यदि आप धागे का पुन: उपयोग नहीं कर सकते हैं, तो इसका उपयोग क्यों करें (यानी यह क्या फायदे हैं)?

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

+0

महान प्रतिक्रिया! मेरे कई सवालों के जवाब देने के लिए समय निकालने के लिए धन्यवाद। :) – john

1

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

1

ऐसा लगता है कि यह डिज़ाइन द्वारा किया गया है।

मुझे एक ही समस्या का सामना करना पड़ा और धागा को फिर से बनाने का एकमात्र समाधान था। मेरे मामले में मैं अक्सर थ्रेड को पुनरारंभ नहीं कर रहा था इसलिए मैंने आगे नहीं देखा।

एक बंद कर दिया या निरस्त किया गया धागा फिर से नहीं कहा जा सकता है:

एक खोज अब this thread on social.msdn जहां स्वीकार किए जाते हैं जवाब राज्यों कर दिया गया है।

MSDN दोहराने इस रूप में अच्छी तरह:

एक धागा है कि समाप्त कर दिया है पर प्रारंभ फोन करके एक गर्भपात धागा पुनः आरंभ करने की कोशिश कर रहा एक ThreadStateException फेंकता है।

0

यह सिर्फ पृष्ठभूमि मोड में है। ऐसा लगता है कि आपको थ्रेडपूल का उपयोग करने की आवश्यकता है क्योंकि थ्रेड ऑब्जेक्ट्स को फिर से शुरू करना और फिर से बनाना बहुत महंगा संचालन है। यदि आपके पास लंबी चल रही नौकरी है जो आपकी मुख्य प्रक्रिया से अधिक समय तक चल सकती है, तो Windows सेवा के उपयोग पर विचार करें।

1

for(;;){} या while(true){} धागे को 'पुन: उपयोग' करने के लिए उपयोगी संरचनाएं हैं। आम तौर पर, थ्रेड इन लूप के शीर्ष पर कुछ सिंक्रनाइज़ेशन ऑब्जेक्ट पर प्रतीक्षा करता है। आपके उदाहरण में, आप किसी ईवेंट या सेमफोर पर प्रतीक्षा कर सकते हैं और इसे अपने बटन OnClick() हैंडलर से सिग्नल कर सकते हैं।

3

Thread.Start प्रलेखन कहते हैं:

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

थ्रेड पुन: प्रयोज्य नहीं हैं। कुछ समय पहले मुझे इस समस्या का सामना करना पड़ा है, समाधान जब भी आवश्यक हो तो नया Thread उदाहरण बनाना था।

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