2011-04-06 14 views
5

मैंने एक बहुत समझदार व्यक्ति से सुना है कि थ्रेड में एक अपवाद फेंक दिया गया है (और पकड़ा नहीं गया है) पैरेंट थ्रेड के लिए प्रचारित किया जा रहा है। क्या यह सच है? मैंने इस तरह कुछ करने की कोशिश की है लेकिन निर्माण धागे में अपवाद नहीं पकड़ सका।बहुप्रचारित अनुप्रयोग में अपवाद।

static void Main(string[] args) 
    { 
     ParameterizedThreadStart pts = 
      new ParameterizedThreadStart(ThreadMethod); 
     try 
     { 
      Thread t = new Thread(pts); 
      t.Start(new object()); 
      Console.ReadLine(); 
     } 
     catch (Exception ex) //the exception is not caught 
     { 
      Debugger.Break(); 
     } 
    } 


    static void ThreadMethod(object @object) 
    { 
     Thread.Sleep(2000); 
     throw new IndexOutOfRangeException(); 
     Thread.CurrentThread.Abort(); 
    } 
+0

मुझे यकीन है कि यह केवल धागा उस पर होता है, यदि आप एक अपवाद उपयोग http://msdn.microsoft.com/en-us/library/system पकड़ा है अगर देखना चाहता हूँ में फेंक होगा। इसके बजाए घटक model.backgroundworker.runworkercompleted.aspx पृष्ठभूमि कार्यकर्ता –

उत्तर

10

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

आप इन अपवादों को पकड़ सकते हैं (आमतौर पर उन्हें लॉग इन करने के लिए) AppDomain.UnhandledException में हुक करके। आदि जानकारी के लिए उस पृष्ठ, विंडोज फॉर्म्स अनुप्रयोगों में मतभेद सहित

1

नहीं, यह नहीं होगा। थ्रेड अपवादों को पकड़ने के लिए आपको एप्लिकेशन का उपयोग करने की आवश्यकता है। थ्रेड अपवाद।

1

सी # में थ्रेडिंग पर एक सभ्य संसाधन अपवाद संचालन के लिए एक अनुभाग है कि: Threading in C#

1

अपवाद कॉल-ढेर में ऊपर की तरफ से प्रचार।

यदि आप एक निश्चित विधि से एक नया धागा शुरू करते हैं, तो यह उस विधि तक पहुंचने तक ऊपर की ओर फैल जाएगा।

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

0

यहाँ यह पकड़ने और एक सुरक्षित तरीके से निपटने का एक तरीका है देखें:

BackgroundWorker bg = new BackgroundWorker(); 
object o; 
bg.DoWork += (c1,c2) => 
{   
     Thread.Sleep(2000);   
     throw new IndexOutOfRangeException(); 
}; 

bg.RunWorkerCompleted += (c3,c4) => 
{ 

if (((RunWorkerCompletedEventArgs)e).Error != null) 
    { 
     MessageBox.Show(((RunWorkerCompletedEventArgs)e).Error.Message); 
    } 
}; 
1

संक्षेप में, नहीं, यह नहीं करता है। आप स्पष्ट पास कुछ विकल्प होते हैं:। में #

  1. विधि में यह लॉग आउट अपने नए धागा शुरू होता है (बनाया थ्रेड के लिए ढेर के ऊपर)
  2. अतुल्यकालिक प्रतिनिधि की तरह एक निर्माण, उपयोग जो होगा जब आप अंत आविष्कार कहते हैं तो अपवाद वापस करें, जिसे आप सामान्य तरीके से पकड़ सकते हैं।
1

एक अपवाद केवल थ्रेड पर पकड़ा जा सकता है, जिससे आया है। तो किसी अन्य थ्रेड पर अपवाद फेंकने से कोई अन्य थ्रेड इसे पकड़ने का कारण नहीं बनता है।

"पैरेंट" थ्रेड की कोई अवधारणा नहीं है।

0

विशेष मामले के लिए एक बहुत ही सरल समाधान है जब मुख्य धागा अन्य धागे के पूरा होने की प्रतीक्षा करता है (https://msdn.microsoft.com/en-us/library/58195swd(v=vs.110).aspx#Examples देखें)। इसके लिए केवल एक वर्ग अपवाद चर की आवश्यकता है।

एक अपवाद हैंडलर द्वारा पूरा संशोधित कोड नमूना इस तरह दिख सकता है।

using System; 
using System.Threading; 

class WaitOne 
{ 
    static AutoResetEvent autoEvent = new AutoResetEvent(false); 
    static Exception SavedException = null; 

    static void Main() 
    { 
     Console.WriteLine("Main starting."); 

     ThreadPool.QueueUserWorkItem(
      new WaitCallback(WorkMethod), autoEvent); 

     // Wait for work method to signal. 
     autoEvent.WaitOne(); 
     if (SavedException != null) 
     { 
      // handle this exception as you want 
     } 

     Console.WriteLine("Work method signaled.\nMain ending."); 
    } 

    static void WorkMethod(object stateInfo) 
    { 
     Console.WriteLine("Work starting."); 

     // Simulate time spent working. 
     try 
     { 
      Thread.Sleep(new Random().Next(100, 2000)); 
      throw new Exception("Test exception"); 
     } 
     catch (Exception ex) 
     { 
      SavedException = ex; 
     }    

     // Signal that work is finished. 
     Console.WriteLine("Work ending."); 
     ((AutoResetEvent)stateInfo).Set(); 
    } 
} 
संबंधित मुद्दे