2013-08-01 5 views
5

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

public void runTest(DateTime deadline) 
{ 
    testThread = new Thread(() => 
    { 
     try 
     { 
      Console.WriteLine("test thread started at " + DateTime.Now.ToShortTimeString()); 
      while (true) { } 
     } 
     finally 
     { 
      Console.WriteLine("test thread entered FINALLY at " + DateTime.Now.ToShortTimeString()); 
      while (true) { } 
     } 
    }); 
    testThread.Start(); 
    while (testThread.IsAlive && deadline.Subtract(DateTime.Now).TotalSeconds > 0) 
    { 
     Console.WriteLine("main thread while loop " + DateTime.Now.ToShortTimeString()); 
     Thread.Sleep(10000); 
    } 
    if (testThread.IsAlive) 
     testThread.Abort(); 
    Console.WriteLine("main thread after abort call " + DateTime.Now.ToShortTimeString()); 
} 

मैं क्या लगता है जब यह चल रहा है कि सांत्वना कभी नहीं अंत में ब्लॉक में प्रवेश का उल्लेख है। आवेदन .abort कॉल के बाद जारी है जैसे कि आखिरकार कोई ब्लॉक नहीं है। क्या मुझसे कुछ गलत हो रही है? कंसोल को अंतिम लिखने तक पहुंचने से पहले आखिरकार ब्लॉक को पास नहीं करना चाहिए या निष्पादन आदेश अभी भी इस तथ्य का एक कार्य है कि आखिरकार एक अलग धागे या कुछ में है?

+0

मैं कोड भाग गया और मैं 'परीक्षण धागा 03:21 PM' पर अंत में प्रवेश किया मिलता है।/कुछ है कि रिहाई निर्माण में बाधित नहीं किया जा सकता है में JITed किए जाने की संभावना अनंत लूप के रूप में कोई डिबगर संलग्न विन्यास – Romoku

+0

की कोशिश की नहीं है, लेकिन मैं कोड डिबग के बीच अलग तरह से व्यवहार और जारी करेंगे संदेह है। –

+2

कॉलिंग 'थ्रेड.एबॉर्ट' सिर में ड्राइवर को शूटिंग करके कार को रोकने की तरह है। कार रुक जाएगी, लेकिन इस बीच कोई घटना नहीं हो सकती है। आपको वास्तव में * थ्रेड.एबॉर्ट 'को कॉल करने की आवश्यकता नहीं है। यदि आप करते हैं, तो आपको अपने एप्लिकेशन के डिज़ाइन पर फिर से जाना होगा। –

उत्तर

6

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

मुझे यकीन है कि आपका धागा डंप किया जा रहा है क्योंकि आप विधि से बाहर निकलें और इसका संदर्भ खो दें, और इसलिए इसे कचरा कलेक्टर द्वारा एकत्र किया जाता है। TestThread को क्लास के फील्ड सदस्य को बनाने का प्रयास करें और देखें कि क्या होता है।

कि, या आपके पास समानांतर में चलने वाले थ्रेड के बाद दौड़ की स्थिति है: मुख्य धागा अंततः डेटा को आउटपुट कर सकता है (अपवाद महंगा है और पकड़ने या अंत में ब्लॉक तक पहुंचने के लिए समय लेता है) ।

+3

चलने वाले थ्रेड आमतौर पर एकत्र नहीं होते हैं। देखें: http://stackoverflow.com/questions/81730/what-prevents-a-thread-in-c-sharp-from-being-collected –

+0

मेरा अनुभव अलग-अलग है, हालांकि ऐसा लगता है कि आउटपुट शायद दौड़ की स्थिति है मुख्य धागा और थ्रेड थ्रेड? इसके साथ मेरा जवाब अपडेट किया गया, इनपुट @ebyrob – Haney

+0

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

2

finally सामान्यतः छोड़ा नहीं जाना चाहिए।

यह संभव है कि कंसोल ऐप (यह मान लेता है) finally ब्लॉक रन से पहले बाहर निकल रहा है (क्योंकि Thread.Abort() पर कॉल करने के बाद कोई प्रतीक्षा नहीं है)।

यदि आप प्रोग्राम के अंत में Console.ReadLine() डालते हैं तो क्या होता है?

5

कार्यकर्ता थ्रेड फ़ंक्शन में आखिरकार ब्लॉक कार्यकर्ता धागे पर निष्पादित किया जाता है जो मुख्य धागे के समानांतर होता है। यह दौड़ की स्थिति है। निरस्त कॉल के बाद आप कौन से कार्यकर्ता धागे को आखिरकार या मुख्य थ्रेड कोड बता सकते हैं। आप तो एक तुल्यकालिक बीच में बंद करें की जरूरत है आप ऐसा ही कुछ डाल करने के लिए है:

 if (testThread.IsAlive) 
     { 
      testThread.Abort(); 

      bool blnFinishedAfterAbort = testThread.Join(TimeSpan.FromMilliseconds(1000)); 
      if (!blnFinishedAfterAbort) 
      { 
       Console.WriteLine("Thread abort failed."); 
      } 
     } 
     Console.WriteLine("main thread after abort call " + DateTime.Now.ToShortTimeString()); 

ध्यान रखें कि यदि आपने विरासत अपवाद हैंडलिंग सक्षम (http://msdn.microsoft.com/en-us/library/ms228965.aspx देखें) और आप AppDomain_UnahandledException ईवेंट हैंडलर निर्दिष्ट तो ThreadAbortException होगा वर्कर थ्रेड फ़ंक्शन में आखिरकार ब्लॉक करने से पहले उस हैंडलर पर लीड निष्पादन। यह निराशाजनक और अप्रत्याशित निष्पादन आदेश का एक और उदाहरण है, जिसे थ्रेड को निरस्त करते समय अवगत होना चाहिए।

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