10

estoy trabajando con los siguientes componentes:BackgroundWorker manejo de excepciones

  • una biblioteca (que se produce una excepción)
  • una prueba de consola para probar mi registro
  • la biblioteca de la empresa bloques de aplicación de manejo de excepciones
  • los bloques de aplicación de la biblioteca de registro de la empresa

estoy invocando el método de biblioteca mediante el uso de un trabajador de fondo. La biblioteca arroja la excepción pero nunca se llama al controlador RunWorkerCompleted.

La única forma de detectar la excepción es rodear mi código de controlador DoWork con un bloque try/catch.

¿No entiende bien la propiedad RunWorkerCompletedEventArgs.Error? ¿No es para obtener excepciones que fueron atrapadas por el BackgroundWorker?

codeSample:

static BackgroundWorker w = new BackgroundWorker(); 

w.DoWork += new DoWorkEventHandler(w_DoWork); 
w.RunWorkerCompleted += 
    new RunWorkerCompletedEventHandler(w_RunWorkerCompleted); 
w.RunWorkerAsync(); 



static void w_DoWork(object sender, DoWorkEventArgs e) 
{ 
    MyClass m = new MyClass(); 
    w.result = m.Compute(); 
} 

static void w_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    if (e.Error != null) 
    { 
     HandleException(e.Error); 
    } 

    /* result related code */ 

} 


static void HandleException(Exception e) 
{ 
    ExceptionPolicy.HandleException(e, "MyPolicy"); 
} 

La muestra anterior conduce a una terminación de mi aplicación de consola. La salida del vs2010 no escribe absolutamente nada (solo salida predeterminada).

Entonces, ¿dónde está el problema?

// Editar: este fragmento funciona para detectar la excepción de la biblioteca.

static void w_DoWork(object sender, DoWorkEventArgs e) 
{ 
    try 
    { 
     MyClass m = new MyClass(); 
     w.result = m.Compute(); 
    }catch(Exception e){ } 

} 
+1

¿Tiene algo en el hilo principal que impida que termine? Algo así como un tiempo (verdad)? – dcarneiro

+0

¿Estás 100% seguro de que RunTorkerCompleted nunca se llama? Aquí hay una pregunta de SO que demuestra que esto debería funcionar ... http: //stackoverflow.com/questions/1044460/unhandled-exceptions-in-backgroundworker –

+1

¿No puedes depurar y ver qué pasa? ¿Qué devuelve HandleException()? – Reniuz

Respuesta

7

Ese es el patrón correcto para BackgroundWorker.

Sospecho que el problema es que su método Main se está saliendo antes de que el BW se haya completado.

RunWorkerAsync volverá de inmediato y si no está esperando en Main, entonces su proceso terminará, tal vez incluso antes de que el BW haya comenzado, no importa completado.

Intente agregar Console.ReadLine al final de su método Main.


Fuera de interés:

BW se comporta de manera diferente en una aplicación de consola y una aplicación de Windows. Si usa una aplicación WinForms o WPF, habrá un SynchronizationContext derivado en su subproceso de interfaz de usuario y BW alineará RunWorkerCompleted de nuevo al subproceso de la interfaz de usuario y lo ejecutará allí. Ese es uno de los principales beneficios de BW.

En una aplicación de consola, se usa el SynchronizationContext predeterminado y esto dirige RunWorkerCompleted a un subproceso de grupo de subprocesos. Esto significa que puede bloquear el hilo Main y el controlador completo seguirá ejecutándose.

+0

Muchas gracias :) – csteinmueller

+0

He tomado una aplicación de consola, porque es la forma más rápida de probar una biblioteca. Me lleva mucho más tiempo presentar mis resultados en una aplicación WPF. – csteinmueller

+7

@MartinJames Paso una gran parte de mi tiempo escribiendo aplicaciones de consola que se programan y ejecutan en servidores. Una IU no sería útil ni factible para tales situaciones. También es algo más fácil hacer pruebas simples en una aplicación de consola; menos sobrecarga implica solo hacer algo simple y ver los resultados. – Servy