2008-10-09 18 views
13

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

उदाहरण:

public class frmMyForm : System.Windows.Forms.Form 
{ 
    /// <summary> 
    /// Create a thread 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    private void btnTest_Click(object sender, EventArgs e) 
    { 
     try 
     { 
      //Create and start the thread 
      ThreadExample pThreadExample = new ThreadExample(this); 
      pThreadExample.Start(); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message, Application.ProductName); 
     } 
    } 

    /// <summary> 
    /// Called from inside the thread 
    /// </summary> 
    /// <param name="ex"></param> 
    public void HandleError(Exception ex) 
    { 
     //Invoke a method in the GUI's main thread 
     this.Invoke(new ThreadExample.delThreadSafeTriggerScript(HandleError), new Object[] { ex }); 
    } 

    private void __HandleError(Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 

मेरी धागा वर्ग का उदाहरण:

public class ThreadExample 
{ 
    public delegate void delThreadSafeHandleException(System.Exception ex); 

    private Thread thExample_m; 

    frmMyForm pForm_m; 
    private frmMyForm Form 
    { 
     get 
     { 
      return pForm_m; 
     } 
    } 

    public ThreadExample(frmMyForm pForm) 
    { 
     pForm_m = pForm; 

     thExample_m = new Thread(new ThreadStart(Main)); 
     thExample_m.Name = "Example Thread"; 
    } 

    public void Start() 
    { 
     thExample_m.Start(); 
    } 

    private void Main() 
    { 
     try 
     { 
      throw new Exception("Test"); 
     } 
     catch (Exception ex) 
     { 
      Form.HandleException(ex); 
     } 
    } 
} 

उत्तर

17

तो आप इसे देखने के द्वारा यूआई थ्रेड पर वापस मार्शल के लिए Invoke का उपयोग कर रहे हैं - जो आपको करने की ज़रूरत है। मैं व्यक्तिगत रूप से एक्शन < अपवाद> सादगी के लिए, और संभावित रूप से InvIn की बजाय BeginInvoke का उपयोग करता हूं, लेकिन मूल रूप से आप सही काम कर रहे हैं।

+0

धन्यवाद, मैंने कभी भी एक्शन का उपयोग कभी नहीं किया है। अच्छा सुझाव। – Jeremy

1

धागे के बीच अपवाद फेंकने आसान नहीं है और शायद वांछित नहीं है। इसके बजाय आप एक साझा डेटा संरचना या चर का उपयोग करके अपवाद पास कर सकते हैं और पहले थ्रेड पर प्रतीक्षा करने के लिए प्रतीक्षा करेंडल का उपयोग कर सकते हैं।

2

शायद एक बेहतर तरीका फॉर्म के संदर्भ के बजाय धागे में एक प्रतिनिधि को पास करना होगा।

5

इसके बजाय .NET Framework में BackgroundWorker क्लास का उपयोग करें। यह एक अलग धागे पर यूआई काम करने के लिए सबसे अच्छा अभ्यास है।

0

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

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