2011-03-07 7 views
6

Cada vez que un hilo en mi ThreadPool arroja una excepción, mi código parece estar atascado en el bloque catch dentro de la función de hilo. ¿Cómo devuelvo la excepción al hilo principal?C# ThreadPool QueueUserWorkItem Manejo de excepciones

+1

posible duplicado de [¿Cómo atrapar excepciones de un ThreadPool.QueueUserWorkItem?] (Http://stackoverflow.com/questions/753841/how-to-catch-exceptions-from-a-threadpool-queueuserworkitem) – Henrik

+0

Duplicado: http://stackoverflow.com/questions/753841/how-to-catch-exceptions-from-a-threadpool-queueuserworkitem – Nick

+0

esos métodos no funcionan. Recibo una excepción que dice 'El hilo de llamada debe ser STA, porque muchos componentes de UI lo requieren. ' – Aks

Respuesta

4

La mejor práctica es que sus hilos de fondo no arrojen excepciones. Permita que manejen sus excepciones por sí mismos.

Idealmente, debe ajustar el código en su método que se ejecuta en un subproceso en un bloque try-catch y manejar la excepción en el bloque catch. No lo vuelvas a lanzar desde el bloque catch.

Lea esto para obtener más detalles. http://www.albahari.com/threading/#_Exception_Handling

Si desea actualizar la interfaz de usuario desde el hilo de fondo, puede hacerlo utilizando la propiedad Control.InvokeRequired y el método Control.Invoke. Vea los enlaces de MSDN para más detalles y ejemplos.

+0

Pero mi UI tiene que mostrar la excepción. ¿Que puedo hacer? – Aks

+0

@Aks - vea la respuesta actualizada. –

+1

Captúrelo en la secuencia y utilice una cola (tubería) para enviar un mensaje de vuelta a la secuencia de la interfaz de usuario para mostrar el error. Las excepciones sobre los bordes de los hilos son algo malo y muy difíciles de solucionar. –

4

No es posible transferir la excepción de un hilo a otro. ¿Qué se puede hacer es incorporado un mecanismo de sincronización para transferir información de excepción entre los hilos y luego lanzar una nueva excepción del objetivo de rosca algo como:

class Program 
{ 
    Exception _savedException = null; 
    AutoResetEvent _exceptionEvent = new AutoResetEvent(false); 

    static void Main(string[] args) 
    { 
     Program program = new Program(); 
     program.RunMain(); 
    } 

    void RunMain() 
    { 
     ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadMethod)); 

     while (true) 
     { 
      _exceptionEvent.WaitOne(); 
      if (_savedException != null) 
      { 
       throw _savedException; 
      } 
     } 
    } 

    void ThreadMethod(object contxt) 
    { 
     try 
     { 
      // do something that can throw an exception 
     } 
     catch (Exception ex) 
     { 
      _savedException = ex; 
      _exceptionEvent.Set(); 
     } 
    } 
} 

Si usted tiene una victoria cosas formulario de solicitud son mucho más simples. En la cláusula catch de su hilo, use el método Invoke (o BeginInvoke) de su formulario, proporcionándole los detalles de la excepción. En el método iniciado con Invoke, puede volver a lanzar o tratar su excepción como lo desee.