2008-12-07 18 views
13

मैं कुछ अजीब व्यवहार देख रहा हूँ जब अपवाद फेंक और उन्हें Application.ThreadException ईवेंट हैंडलर में पकड़ने।आंतरिक अपवाद थ्रेडएक्सप्शन हैंडलर तक क्यों पहुंचता है और वास्तविक फेंक दिया अपवाद नहीं?

मूल रूप से नीचे दिए गए नमूने में क्या हो रहा है यह है कि BackgroundWorker के DoWork ईवेंट हैंडलर में एक अपवाद फेंक दिया गया है। RunWorkerCompleted इवेंट हैंडलर मूल अपवाद के रूप में मूल के साथ एक नया अपवाद पुनर्स्थापित करता है।

क्यों भीतरी अपवाद ThreadException ईवेंट हैंडलर में दिखता है और acutal अपवाद उत्पन्न नहीं किया जा रहा? यदि मैं RunWorkerCompleted ईवेंट हैंडलर में आंतरिक अपवाद प्रदान नहीं करता हूं, तो सही अपवाद दिखाई देगा।

using System; 
using System.Windows.Forms; 
using System.ComponentModel; 

namespace WierdExceptionApp 
{ 
    class WierdExceptionForm : Form 
    { 
     BackgroundWorker worker = new BackgroundWorker(); 

     public WierdExceptionForm() 
     { 
      worker.DoWork += new DoWorkEventHandler(worker_DoWork); 
      worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); 
      worker.RunWorkerAsync(); 
     } 

     void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      if (e.Error != null) 
      { 
       throw new Exception("worker_RunWorkerCompleted", e.Error); 
      } 
     } 

     void worker_DoWork(object sender, DoWorkEventArgs e) 
     { 
      throw new Exception("worker_DoWork"); 
     } 

     [STAThread] 
     static void Main() 
     { 
      Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); 
      Application.Run(new WierdExceptionForm()); 
     } 

     static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) 
     { 
      MessageBox.Show(e.Exception.Message); 
     } 
    } 
} 
+0

एस्टाउन्डिंग; यह मुझे साकार करने के बिना वर्षों तक मुझे काट रहा है। मैं उन चीज़ों के लिए कभी-कभी त्रुटि रिपोर्ट देखता हूं जिन्हें मैं कसम खाता हूं। वे बहुत दुर्लभ थे कि उन्हें देखने में काफी समय नहीं लगे, लेकिन अंत में यह कुछ महत्वपूर्ण के साथ हो रहा था, और मुझे एहसास हुआ कि अपवाद रास्ते में बदल रहा था। WTF ?? –

उत्तर

9

RunWorkerCompleted घटना WF पाइपलाइन करता है कि Control.Invoke() काम से यूआई धागा करने के लिए BGW धागे से मार्शल है। अनिवार्य रूप से, संदेश लूप द्वारा खाली किए गए प्रतिनिधियों के साथ एक कतार है। यह कोड जो करता है, Control.InvokeMarshaledCallbacks(), आप इसे कॉल स्टैक पर देखेंगे, अनचाहे अपवादों को पकड़ने के लिए एक पकड़ (अपवाद) खंड है। उस खंड में एप्लिकेशन.ऑन थ्रेड अपवाद, अपवाद का मूल्य गुजर रहा है। गेटबेस अपवाद()।

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

+8

फिर भी * WinForms में एक और * बग जो माइक्रोसॉफ्ट सबसे निश्चित रूप से कभी तय नहीं करता है! – Joshua

+1

वह कितना बेवकूफ है! एमएस निश्चित रूप से इसे कभी ठीक नहीं करेगा क्योंकि यह उनकी आंखों में "ब्रेकिंग चेंज" होगा। फिर भी सभी https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=433765 पर जाएं और वैसे भी समस्या पंजीकृत करें। –

0
 if (e.Error != null) 
     { 
      throw new Exception("worker_RunWorkerCompleted", new Exception("Inner", new Exception("Inner inner"))); 
     } 

आप "भीतरी भीतरी" अंत में मिलता है। ऐसा लगता है कि यह आंतरिक-अपवाद को देखने के लिए Application_ThreadException विधि का व्यवहार है।

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