सी # थ्रेड समाप्ति और थ्रेड ।bort ()


85

MSDN में, थ्रेड.एबोर्ट () विधि का वर्णन कहता है: "इस विधि को कॉल करने से आमतौर पर थ्रेड समाप्त हो जाता है।"

हमेशा क्यों नहीं?

किन मामलों में यह धागे को समाप्त नहीं करता है?

क्या धागे समाप्त करने की कोई अन्य संभावना है?

जवाबों:


60

Thread.Abort()ThreadAbortExceptionधागे पर इंजेक्शन लगाता है । थ्रेड कॉल करके अनुरोध को रद्द कर सकता है Thread.ResetAbort()। इसके अलावा, कुछ निश्चित कोड भाग हैं, जैसे कि finallyब्लॉक जो अपवाद को संभालने से पहले निष्पादित करेगा। यदि किसी कारण से थ्रेड ऐसे ब्लॉक में फंस गया है तो अपवाद कभी भी थ्रेड पर नहीं उठाया जाएगा।

चूंकि कॉल करते समय थ्रेड की स्थिति पर कॉलर का बहुत कम नियंत्रण होता है Abort(), इसलिए आमतौर पर ऐसा करना उचित नहीं होता है। इसके बजाय समाप्ति का अनुरोध करने वाले थ्रेड को संदेश भेजें।


किस तरह का संदेश? क्या आपका मतलब एक विधि आह्वान है?
user101375

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

मेरे धागे की एक बड़ी समस्या यह है कि मस्तूल हल किया जाता है, कोई कार्य कतार नहीं था।
13

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

54

किन मामलों में यह धागे को समाप्त नहीं करता है?

यह प्रश्न एक डुप्लिकेट है।

Thread.Abort () का उपयोग करने में क्या गलत है

क्या धागे को समाप्त करने के लिए कोई अन्य सकारात्मकता है?

हाँ। आपकी समस्या यह है कि आपको कभी भी एक ऐसा सूत्र शुरू नहीं करना चाहिए जिसे आप विनम्रतापूर्वक रोक नहीं सकते, और यह समय पर रुक जाता है। यदि आप ऐसी स्थिति में हैं, जहां आपको एक ऐसा धागा शुरू करना है, जिसे रोकना मुश्किल (1) हो सकता है, (2) छोटी गाड़ी, या सबसे खराब (3) उपयोगकर्ता के लिए शत्रुतापूर्ण है, तो सही काम करना है एक नई प्रक्रिया, नई प्रक्रिया में थ्रेड प्रारंभ करें, और फिर जब आप थ्रेड को नीचे जाने के लिए प्रक्रिया को समाप्त करें । केवल एक चीज जो अनकॉपरेटिव थ्रेड की सुरक्षित समाप्ति की गारंटी दे सकती है, वह है ऑपरेटिंग सिस्टम इसकी पूरी प्रक्रिया को ले रहा है।

अधिक विवरण के लिए इस प्रश्न का मेरा अत्यधिक लंबा उत्तर देखें:

C # में लूप के भीतर लॉक स्टेटमेंट का उपयोग करना

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


एरिक, मुझे विनम्रतापूर्वक एक थ्रेड को कैसे रोकना चाहिए अगर वह थ्रेड एक सिंक्रनाइज़ेशन ऑब्जेक्ट पर प्रतीक्षा कर रहा है, जैसे कि EventWaitHandle.WaitOne () ;?
कोर्विन

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

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

@Corvin: आपके पास एक लूप हो सकता है जो इवेंट के लिए प्रतीक्षा करता है (थोड़े समय के लिए), फिर जाँचता है कि क्या यह प्रतीक्षा करने की कोशिश बंद कर देनी चाहिए (ताकि यह सामान्य रूप से बाहर निकल सके)। इस तरह, आप अपने धागे को संकेत दे सकते हैं कि इसे बंद कर देना चाहिए, और आपको इसे रोकने के लिए केवल अपना समय समाप्त होने तक इंतजार करना चाहिए।
केविन किबलर

2
@Corvin, यदि आप उस प्रतीक्षा थ्रेड को बैकग्राउंड थ्रेड बनाते हैं, तो आपको एप्लिकेशन क्विट होने से पहले इसे बंद नहीं करना चाहिए।
डॉन किर्कबी

17

हमेशा क्यों नहीं? किन मामलों में यह धागे को समाप्त नहीं करता है?

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

ThreadAbortException ज्यादा है:

जब थ्रेड को नष्ट करने के लिए एबॉर्ट विधि से कॉल किया जाता है, तो सामान्य भाषा रनटाइम एक थ्रेडबोर्टएक्ससेप्शन फेंकता है। ThreadAbortException एक विशेष अपवाद है जिसे पकड़ा जा सकता है, लेकिन यह स्वचालित रूप से फिर से पकड़ ब्लॉक के अंत में उठाया जाएगा। जब यह अपवाद उठाया जाता है, तो रनटाइम थ्रेड को समाप्त करने से पहले सभी अंत में ब्लॉक निष्पादित करता है। चूंकि थ्रेड अंतत: ब्लॉक में एक अनबिकेड कम्प्यूटेशन कर सकता है, या एबॉर्ट Thread.ResetAbort()को रद्द करने के लिए कॉल कर सकता है, इस बात की कोई गारंटी नहीं है कि थ्रेड कभी खत्म हो जाएगा।

आपको Abort()मैन्युअल रूप से थ्रेड की आवश्यकता नहीं है । सीएलआर आपके लिए सभी गंदे काम करेगा यदि आप बस थ्रेड रिटर्न में विधि करते हैं; वह धागा सामान्य रूप से समाप्त हो जाएगा।


मुझे एबॉर्ट () की जरूरत है, क्योंकि उस धागे पर एक संदेश लूप शुरू हुआ (डिस्पैचर.रुण ();))। अगर मुझे यह सही समझ में आता है, तो मुझे इसे समाप्त करने के लिए थ्रेड में रिटर्न कॉल करने वाली विधि को लागू करने की आवश्यकता है?
user101375

7

FileStream.Read()एक नामित पाइप जो वर्तमान में कुछ भी प्राप्त नहीं कर रहा है (आने वाले डेटा की प्रतीक्षा करते समय कॉल ब्लॉक पढ़ें) इसका जवाब नहीं देगा Thread.Abort()। यह Read()कॉल के अंदर रहता है ।


6

क्या होगा यदि एक धागा एक ताला पकड़े हुए है और गर्भपात / मार डाला गया है? संसाधन अटके हुए हैं

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

संदर्भ MSDN


देखें: प्रबंधित सर्वोत्तम अभ्यास


5

मुझे लगता है कि लूप में फंसे एक धागे को नष्ट नहीं किया जा सकता है:

//immortal
Thread th1 = new Thread(() => { while (true) {}});

मैं हालांकि धागे को समाप्त कर सकता हूं यदि लूप के दौरान सोता है:

//mortal
Thread th2 = new Thread(() => { while (true) { Thread.Sleep(1000); }});

1
यह सच नहीं प्रतीत होता है, मैंने एक परीक्षण कार्यक्रम चलाया: `{var th = new Thread () (> = int i = 0; try {the (true) {i ++;}} catch (Exception e) { Console.WriteLine ("aborting @ {0}", i);}}); th.Start (); Thread.Sleep (1000); th.Abort (); th.Join (); }
वीपेंग एल


3

क्योंकि आप हैंडलर के अंदर ThreadAbortExceptionकॉल और कॉल कर सकते हैं Thread.ResetAbort



-1

मेरे पास ऐसे मामले हैं जहां धागा एबोर्ट () कॉल को सुनने के लिए बहुत व्यस्त हो गया है, जिसके परिणामस्वरूप आमतौर पर थ्रेडबोर्टिंग अपवाद में मेरे कोड को फेंक दिया जाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.