2008-10-09 8 views
13

Ich habe eine Methode in einem separaten Thread ausgeführt. Der Thread wird erstellt und von einem Formular in einer Windows-Anwendung gestartet. Wenn eine Ausnahme innerhalb des Threads ausgelöst wird, geben Sie sie am besten an die Hauptanwendung zurück. Im Moment übergebe ich einen Verweis auf das Hauptformular in den Thread, führe dann die Methode aus dem Thread aus und verursache, dass die Methode vom Hauptanwendungs-Thread aufgerufen wird. Gibt es einen Best-Practice-Weg, dies zu tun, weil ich mich nicht damit auskenne, wie ich es jetzt mache?Abfangen von Ausnahmen von einem anderen Thread

Beispiel meiner Form:

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); 
    } 
} 

Beispiel meiner Thread-Klasse:

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); 
     } 
    } 
} 

Antwort

17

Sie verwenden Invoke also, um zurück zum UI-Thread zu gelangen, so wie es aussieht - genau das, was Sie tun müssen. Ich würde persönlich eine Aktion verwenden < Ausnahme> der Einfachheit halber und möglicherweise BeginInvoke statt Invoke, aber im Grunde machst du das Richtige.

+0

Danke, ich habe noch nie Action zuvor verwendet. Guter Vorschlag. – Jeremy

1

Ausnahmen zwischen Threads zu werfen ist nicht einfach, und wahrscheinlich nicht erwünscht. Stattdessen können Sie die Ausnahme mit einer gemeinsam genutzten Datenstruktur oder -variablen übergeben und waitHandle verwenden, um auf den ersten Thread zu warten.

2

Wahrscheinlich wäre ein besserer Weg, einen Delegaten in den Thread statt eines Verweises auf das Formular selbst zu übergeben.

5

Verwenden Sie stattdessen die BackgroundWorker-Klasse im .NET-Framework. Dies ist die beste Vorgehensweise zum Ausführen von UI-Arbeiten an einem anderen Thread.

0

Ich stimme Dror völlig zu. Formal können wir diese Struktur als FaultContract bezeichnen. Grundsätzlich, wenn eine Ausnahme in einem anderen Thread passiert ist, kann der Client-Thread in diesem Moment kaum etwas tun, außer dass er diese Information sammelt und entsprechend in seinem eigenen Thread agiert. Wenn sich die Thereads in verschiedenen AppPools befinden, gibt es eine zusätzliche Komplexität der Serialisierung (die insgesamt ein separates Thema sein kann).