Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catching Error when using Task.Factory

Tags:

i am using the following

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

then the function i am calling looks like this

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

My problem is an exception is being thrown inside the thread and not being handled.

I have tried wrapping it in a try catch

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

but it still is not catching the error and thus crashing the application.

How can I catch exceptions in the main thread so I can handle them?

Update

I have made the changes recommended below and still it is saying the exception is unhandled

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

then in my DoConfigPage I added another try catch.

In this catch is now where it is crashing and saying the exception being thrown was unhandled, what am I missing?

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

I also tried what Eric J. suggested with the same results

var task = Task.Factory.StartNew(() => DoPrintConfigPage(serial));  try {     task.Wait();                   } catch (AggregateException ex) { MessageBox.Show("something broke"); } 
like image 233
twaldron Avatar asked Feb 14 '13 20:02

twaldron


People also ask

How do you handle exceptions thrown by tasks?

Exceptions are propagated when you use one of the static or instance Task. Wait methods, and you handle them by enclosing the call in a try / catch statement. If a task is the parent of attached child tasks, or if you are waiting on multiple tasks, multiple exceptions could be thrown.

Does await throw AggregateException?

When using await, it's going to unwrap the first exception and return it, that's why we don't hit the catch (AggregateException e) line. But if we use something like the below code sample, we catch the AggregateException , note that it's not a good idea since we're blocking the running thread.

What is task factory StartNew in C#?

StartNew(Action<Object>, Object, CancellationToken, TaskCreationOptions, TaskScheduler) Creates and starts a task for the specified action delegate, state, cancellation token, creation options and task scheduler.


2 Answers

Alternatively, you can chain your task creation and add a ContinueWith:

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

EDIT: This snippet, when run, pops up the message box for me:

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!"); } 
like image 171
JerKimball Avatar answered Sep 20 '22 09:09

JerKimball


Your try block is exited right after you start the new task, because that method just continues to run.

Instead you can catch the Exception as an AggregateException where you wait for the task (or multiple tasks) to complete:

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

like image 25
Eric J. Avatar answered Sep 18 '22 09:09

Eric J.