Error de captura al usar Task.Factory

estoy usando lo siguiente

Task.Factory.StartNew(() => DoPrintConfigPage(serial)); 

entonces la función que estoy llamando se ve así

 private void DoPrintConfigPage(string serial) { //do printing work } 

Mi problema es que se está lanzando una excepción dentro del hilo y no se está manejando.

He intentado envolverlo en un try catch

 try { Task.Factory.StartNew(() => DoPrintConfigPage(serial)); } catch (Exception ex) { } 

pero todavía no está captando el error y, por lo tanto, bloqueando la aplicación.

¿Cómo puedo detectar excepciones en el hilo principal para poder manejarlas?

Actualizar

Realicé los cambios recomendados a continuación y sigo diciendo que la excepción no se ha manejado

 var task = Task.Factory.StartNew(() => DoPrintConfigPage(serial)) .ContinueWith(tsk => { MessageBox.Show("something broke"); },TaskContinuationOptions.OnlyOnFaulted); 

luego en mi DoConfigPage agregué otro try catch.

En esta captura ahora es donde se está estrellando y diciendo que la excepción que se lanzó no fue controlada, ¿qué me estoy perdiendo?

 private void DoPrintConfigPage(string serial) { try { //call the print function } catch (Exception ex) { throw ex; //it is crashing here and saying it is unhandled } } 

También probé lo que sugirió Eric J. con los mismos resultados

 var task = Task.Factory.StartNew(() => DoPrintConfigPage(serial)); try { task.Wait(); } catch (AggregateException ex) { MessageBox.Show("something broke"); } 

Alternativamente, puede encadenar su creación de tareas y agregar un ContinueWith:

 var job = Task.Factory .StartNew(...) .ContinueWith(tsk => { // check tsk for exception and handle }); 

EDITAR: Este fragmento, cuando se ejecuta, muestra el cuadro de mensaje para mí:

 void Main() { var serial = "some serial"; var task = Task.Factory .StartNew(() => DoPrintConfigPage(serial)) .ContinueWith(tsk => { MessageBox.Show("something broke"); var flattened = tsk.Exception.Flatten(); // NOTE: Don't actually handle exceptions this way, m'kay? flattened.Handle(ex => { MessageBox.Show("Error:" + ex.Message); return true;}); },TaskContinuationOptions.OnlyOnFaulted); } public void DoPrintConfigPage(string serial) { throw new Exception("BOOM!"); } 

Su locking de try se cierra justo después de que inicie la nueva tarea, porque ese método simplemente continúa ejecutándose.

En su lugar, puede capturar la excepción como una excepción agregada donde espera que se complete la tarea (o varias tareas):

 var task1 = Task.Factory.StartNew(() => { throw new MyCustomException("I'm bad, but not too bad!"); }); try { task1.Wait(); } catch (AggregateException ae) { // Assume we know what's going on with this particular exception. // Rethrow anything else. AggregateException.Handle provides // another way to express this. See later example. foreach (var e in ae.InnerExceptions) { if (e is MyCustomException) { Console.WriteLine(e.Message); } else { throw; } } } 

http://msdn.microsoft.com/en-us/library/dd997415.aspx

Si no está esperando su tarea, creo que la solución más fácil se encuentra en Task.Exception :

Obtiene la excepción AggregateException que provocó que la tarea finalizara prematuramente. Si la Tarea se completó con éxito o aún no arrojó ninguna excepción, esto dará como resultado nulo.

Estoy usando algo como esto:

 Task.Factory.StartNew(() => DoStuffHere()) .ContinueWith(task => { if (task.Exception != null) Log("log all the exceptions!"); }); 

También debe saber sobre System.Threading.Tasks.TaskScheduler.UnobservedTaskException .

Si está en el negocio de crear instancias de Task “disparar y olvidar”, querrá suscribirse a ese evento al inicio de su progtwig.

Tal vez estás tratando de atrapar una Excepción de Estado Corrupto . Dado que las aplicaciones .NET 4 no pueden detectar tales excepciones de forma predeterminada. Podría intentar agregar la entrada legacyCorruptedStateExceptionsPolicy=true a su archivo de configuración como se indica en el artículo de MSDN vinculado anteriormente.