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?
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"); }
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.
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.
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.
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!"); }
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With