2008-10-09 21 views
13

Tengo un método ejecutándose en un hilo separado. El hilo se crea y se inicia desde un formulario en una aplicación de Windows. Si se lanza una excepción desde el interior del subproceso, ¿cuál es la mejor manera de devolverla a la aplicación principal? En este momento, estoy pasando una referencia al formulario principal en el hilo, luego invocando el método del hilo y haciendo que el hilo principal de la aplicación llame al método. ¿Hay alguna manera de hacer esto para las mejores prácticas porque no me siento cómodo con la forma en que lo estoy haciendo ahora?detectando excepciones de otro hilo

ejemplo de mi formulario:

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

Ejemplo de mi clase de hilo:

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

Respuesta

17

Así que está usando Invoke para volver a la secuencia de la interfaz de usuario, por su aspecto, que es exactamente lo que necesita hacer. Yo personalmente usaría una Acción < Exception> por simplicidad, y posiblemente BeginInvoke en lugar de Invoke, pero básicamente estás haciendo lo correcto.

+0

Gracias, nunca antes he usado la Acción . Buena sugerencia. – Jeremy

1

lanzar excepciones entre los hilos no es fácil y probablemente no deseado. en su lugar, puede pasar la excepción utilizando una estructura o variable de datos compartidos y usar waitHandle para esperar en el primer hilo.

2

Probablemente una mejor manera sería pasar un delegado en el hilo en lugar de una referencia al propio formulario.

5

Utilice en su lugar la clase BackgroundWorker en el marco .NET. Es la mejor práctica para realizar trabajos de IU en un hilo diferente.

0

Estoy totalmente de acuerdo con Dror. De una manera formal, podemos llamar a esta estructura como FaultContract. Fundamentalmente, cuando ha ocurrido una excepción en otro hilo, el hilo del cliente apenas puede hacer algo en ese momento, excepto que para recopilar esa información y actuar en consecuencia en su propio sitio. Si los pasillos están en diferentes AppPool, entonces hay una complejidad extra de Serialización (que puede ser un tema separado por completo).

Cuestiones relacionadas