2009-08-25 15 views
41

मैं थ्रेड को मारने के लिए thread.Abort विधि का उपयोग कर रहा हूं, लेकिन यह काम नहीं कर रहा है। क्या थ्रेड को समाप्त करने का कोई और तरीका है?तुरंत सी # में धागे को कैसे मारें?

private void button1_Click(object sender, EventArgs e) 
{ 
    if (Receiver.IsAlive == true) 
    { 
     MessageBox.Show("Alive"); 
     Receiver.Abort(); 
    } 
    else 
    { 
     MessageBox.Show("Dead"); 
     Receiver.Start(); 
    } 
} 

मैं इस का उपयोग कर रहा है, लेकिन हर बार जब मैं Alive दर्जा मिल, Receiver मेरी वैश्विक धागा है।

+10

खतरे, विल रॉबिन्सन, खतरे! Thread.Abort का उपयोग करने के लिए ** बहुत ** शर्मीली रहें - लगभग हमेशा एक बुरा विचार। –

+4

फिर थ्रेड को मारने के लिए क्या उपयोग किया जाना चाहिए? – Mobin

+3

धागे को रोकने के लिए कहें, और उस पल से धागे को अनदेखा करें। – MSalters

उत्तर

58

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

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

+0

मैं इस तंत्र का उपयोग स्वयं करता हूं। यूआई-आधारित कोड के लिए, मैंने एक वैश्विक चर सेट किया है, और सेवाओं के लिए मैं डेटाबेस तालिका की जांच करता हूं। अच्छा और अनुमानित। –

+5

यदि संभव हो, तो एक चर के बजाय मैन्युअल रीसेट इवेंट का उपयोग करें, इसके लिए उन्हें क्या बनाया गया है। –

+3

अब मैं उत्सुक हूं - प्रारंभिक समाप्ति स्थिति की जांच के लिए मैन्युअल रीसेट इवेंट बेहतर कैसे होगा? मैं समझता हूं कि जब हम किसी चीज़ को अवरुद्ध करते हैं तो वे बेहतर होते हैं, लेकिन यहां कोई अवरोध नहीं होता है। – redtuna

6

धागा इसे खत्म होने पर मारा जाएगा, इसलिए यदि आप लूप या कुछ और का उपयोग कर रहे हैं तो आपको थ्रेड को समाप्त करने के बाद लूप को रोकने के लिए थ्रेड को चर से पास करना चाहिए।

4

सी # थ्रेड.एबॉर्ट तुरंत थ्रेड को निरस्त करने की गारंटी नहीं है। यह शायद तब काम करेगा जब एक थ्रेड अपने आप को रोकता है लेकिन जब कोई थ्रेड किसी अन्य पर कॉल नहीं करता है।

कृपया दस्तावेज़ देखें: http://msdn.microsoft.com/en-us/library/ty8d3wta.aspx

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

14

आपको पहले धागे को समाप्त करने के कुछ सहमत तरीके से होना चाहिए। उदाहरण के लिए एक रनिंग_ वैल्यूएबल है कि थ्रेड जांच और अनुपालन कर सकता है।

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

ThreadInterruptException के मामले में आप चल रहे_ चर को देख सकते हैं कि आपको जारी रखना चाहिए या नहीं। ThreadAbortException के मामले में आपको तत्काल साफ-सफाई करना चाहिए और थ्रेड प्रक्रिया से बाहर निकलना चाहिए।

कोड धागा बंद करने के लिए निम्न करना चाहिए की कोशिश करता है:

running_ = false; 
threadInstance_.Interrupt(); 
if(!threadInstance_.Join(2000)) { // or an agreed resonable time 
    threadInstance_.Abort(); 
} 
+2

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

+0

यदि 'threadInstance_.Interrupt() 'थ्रेड को तेज़ी से समाप्त करता है,' threadInstance_.Join' फेंक देगा * सिस्टम। थ्रेडिंग। थ्रेडस्टेट अपवाद: थ्रेड शुरू नहीं हुआ है * – Hannobo

24

आप तुरंत कि रास्ते में यह कर मार सकते हैं:

private Thread _myThread = new Thread(SomeThreadMethod); 

private void SomeThreadMethod() 
{ 
    // do whatever you want 
} 

[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)] 
private void KillTheThread() 
{ 
    _myThread.Abort(); 
} 

मैं हमेशा इसका इस्तेमाल करते हैं और मेरे लिए काम करता है:)

+0

लेकिन http://stackoverflow.com/a/1560567/199364 देखें , और अन्य उत्तरों का वर्णन करते हुए क्यों thread.abort जोखिम भरा है। – ToolmakerSteve

+2

[एड्रियन रेगन का जवाब] (http://stackoverflow.com/a/1327377/199364) 'abort' का उपयोग करने का एक बहुत सुरक्षित तरीका है - एक अंतिम उपाय के रूप में यदि कोई थ्रेड मर नहीं रहा है। – ToolmakerSteve

-1
private void ResumeButton_Click(object sender, RoutedEventArgs e) 
    { 
     Task.Factory.StartNew(() => 
     { 
      Application.Current.Resources["AutoPilotThreadStatus"] = true; 
      Thread.CurrentThread.Name = "ResumeAutoPilot"; 
      Thread.CurrentThread.IsBackground = true; 
      AutoPilotHandler.ResumeAutoPilot(); 
     }); 
    } 

    public static void ResumeAutoPilot() 
    { 
     while ((bool)Application.Current.Resources["AutoPilotThreadStatus"]) 
     { 
      CheckAutoPilotThreadStatus(); 
      var searchYoutube = YoutubeHandler.Search("small truck"); 
      CheckAutoPilotThreadStatus(); 
      SaveVideosToDatabase(searchYoutube); 
      CheckAutoPilotThreadStatus(); 
     } 
    } 

    public static void CheckAutoPilotThreadStatus() 
    { 
     if (!(bool)Application.Current.Resources["AutoPilotThreadStatus"]) 
     { 
      KillCurrentThread(); 
     } 
    } 

    public static void KillCurrentThread() 
    { 
     Thread.CurrentThread.Abort(); 
    } 
+3

ऐप संसाधनों का उपयोग नहीं किया जाना चाहिए इसका एक आदर्श उदाहरण। –

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