2011-01-23 12 views
5

एक अपवाद फेंक मैं इस तरह धागा है, के बाद मैं उदाहरण देख link textमें धागा सी #

ThreadStart _threadStart = new ThreadStart(delegate() 
{ 
     try 
     { 
      threadFunction(httpContext); 
     } 
     catch (Exception ex) 
     { 
      throw ex; 
     } 
}); 
Thread _thread = new Thread(_threadStart); 
    _thread.Start(); 

जब एक अपवाद हो यह धागा है कि यह शुरू कर दिया में फिर से फेंक दिया dosen't। तो मैं क्या गलत कर रहा हूं या इसे कैसे करना है?

नोट: उन्नत

+6

नोट आप * कभी नहीं * एक अपवाद rethrow की तरह तुम वहाँ क्या करना चाहिए। कैच ब्लॉक में बस 'फेंक'; ' – Joey

+0

मुझे पता है कि मैं – Hiyasat

+1

संदेश के साथ "सिस्टम.एक्सप्शन" से प्राप्त कस्टम अपवाद फेंकता हूं, आपको उस जानकारी के साथ * नया * अपवाद फेंकना है जिसे आप जोड़ना चाहते हैं। * मूल * अपवाद को इनरएक्सप्शन के रूप में पास करें। ऐसा केवल तभी करें जब अतिरिक्त जानकारी उच्च मान का है क्योंकि इससे समस्या निवारण अधिक कठिन हो जाता है। –

उत्तर

7

अपवाद फेंक दिया जाएगा, लेकिन यह केवल धागे को समाप्त करेगा। अपवाद को उस धागे में फिर से नहीं फेंक दिया गया है जिसने इसे शुरू किया था।

+0

पर नहीं डाला गया है क्यों? और ऐसा करने का सबसे अच्छा समाधान क्या है? – Hiyasat

+1

@ हियासैट: यदि कोई धागा किसी भी समय अपने शुरुआती धागे में कोई अपवाद फेंक सकता है, तो इसे संभालने के लिए शुरुआती धागे को लागू करना बहुत कठिन होगा। आपको अपवाद को शुरुआती धागे पर वापस संवाद करना होगा जैसे आप किसी अन्य परिणाम को वापस भेजते हैं, उदाहरण के लिए एक धागे का उपयोग करके दोनों धागे तक पहुंच हो। – Guffa

1

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

यदि आप उदाहरण के लिए फ़ाइल में अपवाद लॉग करते हैं, तो मुझे यकीन है कि आप इसे देखेंगे। :)

+0

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

+0

मुझे यकीन है कि अपवाद होता है लेकिन यह मुख्य धागे – Hiyasat

2

क्या आप सुनिश्चित हैं कि अपवाद फेंक दिया गया है? यदि कोई थ्रेड अपवाद के साथ विफल रहता है, तो पूरा एप्लिकेशन क्रैश हो जाएगा, जिसे आप AppDomain.CurrentDomain.UnhandledException ईवेंट का उपयोग करके नोटिस कर सकते हैं (ध्यान दें कि जब तक ईवेंट निकाल दिया गया है, तो आप अपने एप्लिकेशन को समाप्त होने से नहीं रोक सकते हैं, लेकिन संसाधनों को साफ और सहेज सकते हैं महत्वपूर्ण डेटा - अधिक जानकारी के लिए घटना प्रलेखन देखें)।

कोई धागा है कि जन्म देती है एक शीर्ष स्तर अपवाद एक बड़ी समस्या इंगित करता है:

लेकिन, धागा आप के लिए भेजा से accepted answer उद्धृत करने के लिए।

आपको अपवाद लॉगिंग करने और/या अन्य धागे को सिग्नल करने का प्रयास करना चाहिए कि यह थ्रेड विफल हो गया है।

0

मुझे लगता है कि आपको शायद BackgroundWorker कक्षा का उपयोग करना चाहिए। आप RunWorkerCompleted ईवेंट की सदस्यता ले सकते हैं, और इसमें Error संपत्ति है जिसमें आपका अपवाद होगा।

+0

धन्यवाद, लेकिन मुझे .NET 4 कार्य में कुछ और शक्तिशाली मिला http://blogs.msdn.com/b/pfxteam/archive/2009/05/31/9674669.aspx – Hiyasat

+0

लिंक के लिए धन्यवाद - कार्य बहुत अच्छे लगते हैं, मैं उन्हें अभी तक जांचने का मौका नहीं मिला है। – antsyawn

6

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

private static void RebelWithoutACause() 
{ 
    throw new NullReferenceException("Can't touch this!"); 
} 

की आप एक नया धागा है कि अपने कार्यक्रम में इस विधि कॉल बनाने के लिए, और एक सुरक्षित प्रोग्रामर किया जा रहा है, तो आप एक में काम लिफाफे में तय मान लीजिए:

उदाहरण के लिए, यदि आप एक विद्रोही विधि है कहना try/catch ब्लॉक:

private static void Main(string[] args) 
{ 
    try 
    { 
     var thread = new Thread(RebelWithoutACause); 
     thread.Start(); 
     thread.Join(); 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(ex.ToString()); 
    } 
} 

हालांकि, अगर आप डीबगर में इस चलाने के लिए, आपको पता चल जाएगा कि आप catch ब्लॉक करने के लिए कभी नहीं मिलेगा, और बदले धागा को मार डाला जाएगा, और डिबगर है कि आप शिकायत एक अनचाहे अपवाद है ।

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

+0

बहुत अच्छी व्याख्या! – koumides

0

शायद कुछ इस तरह करते हैं:

const int numThreads = 8; 
    Thread[] threads = new Thread[numThreads]; 
    Exception[] threadsExceptions = new Exception[numThreads]; 
    for (int i = 0; i < numThreads; i++) { 
     threadsExceptions[i] = null; 
     int closureVariableValue = i; 
     ThreadStart command =() => 
     { 
      try 
      { 
       throw new ArgumentException("thread_" + closureVariableValue + "'s exception"); 
      }catch(Exception any) 
      { 
       threadsExceptions[closureVariableValue] = any; 
      } 
     }; 
     threads[i] = new Thread(command); 
     threads[i].Start(); 
    } 
    for(int i = 0; i < numThreads; i++) 
    { 
     threads[i].Join(); 
     if (threadsExceptions[i] != null) 
     { 
      throw threadsExceptions[i]; 
     } 
    } 
संबंधित मुद्दे