3

I have a couple of chained tasks that are kicked off using Task.Factory.StartNew(...

After some serious pain they are running great. Now I'm going back to try to add better error checking for Tasks since that was much of the pain in getting the tasks to work correctly.

I have created a small WPF app just to test one task and try to trap errors. I have this as a "Last Resort" kind of error trap.

TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;

However, I want to trap errors before this and try to deal with them gracefully.

Testing this small task:

        Task[] tasks = new Task[1];

        MessageBox.Show("Before Tasks");

        tasks[0] = Task.Factory.StartNew(DoBackgroundTask).ContinueWith(
            w =>
            {
                MessageBox.Show("OnlyOnRanToCompletion");

            }
            , token, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler);

The Background task is as follows (one line to test success and the other to test failure. Commented out depending on what I'm working on):

    private void DoBackgroundTask()
    {
        var two = 1 + 1;

        //throw new Exception("Test");
    }

I have a wait and error check after the task StartNew just to pause and allow me to catch the error before it goes to TaskScheduler_UnobservedTaskException

    try
    {
        tasks[0].Wait();
    }
    catch (AggregateException aex)
    {
        Messages.inform(aex.InnerException.Message);
    }

I might be misunderstanding the proper way to handle task / thread errors, but here are my problems:

1) When I use any other Task Continuation Option other than None. My ContinueWith code is not executed. I would really like to do something on cancel / faulted / not ran to completion.

2) Not sure that the task.Wait() and TaskContinuation method together is the best way to trap and handle errors, but I can't find another way.

3) I would like to Chain my task continuation options. For example. Piece of code that handles OnlyOnRanToCompletion and a another section that handles NotOnRanToCompletion. I can't seem to get them to work together.

In Short using anything other than TaskContinuationOptions.None with task.Wait() catch aggregateexception seems to work.

All else HANGS...

I'm I going about this wrong?

Thanks!

UPDATE - This Works:

        tasks[0] = Task.Factory.StartNew(DoBackgroundTask);
        tasks[1] = tasks[0].ContinueWith(
            ant =>
            {
                // Check task status.
                switch (tasks[0].Status)
                {
                    // Handle any exceptions to prevent UnobservedTaskException.             
                    case TaskStatus.RanToCompletion:
                        // do stuff 
                        break;
                    case TaskStatus.Faulted:
                        if (tasks[0].Exception != null)
                            Messages.inform(tasks[0].Exception.InnerException.Message);
                        else
                            Messages.inform("Operation failed!");
                        break;
                    default:
                        break;
                }
            }
            );

Seems like when I do a .ContinueWith off the StartNew of main task it does not seem to work well. When I create a second task that is created with a .ContinueWith off the first task... we are in business. I really don't understand the difference. Looks like they should both work.

pStan
  • 1,084
  • 3
  • 14
  • 36
  • 1
    What framework version are you on? This is often easier with async/await... – Reed Copsey Jan 21 '15 at 22:44
  • Looking at this answer now http://stackoverflow.com/questions/15605860/task-cancellation-and-taskcontinuationoptions I have a small test case working using .ContinueWith and then checking task1.Status... I might see if I can get a larger example working using this method. – pStan Jan 21 '15 at 22:59
  • "I would really like to do something on cancel / faulted / not ran to completion" -- you're not making sense. The code you posted passes `TaskContinuationOptions.OnlyOnRanToCompletion`. If you want continuation on states other than `RanToCompletion`, why are you passing that option? All the code you posted seems to be behaving correctly...but you don't like the way it behaves, so why did you write the code that way? – Peter Duniho Jan 22 '15 at 07:08
  • Sorry for the confusion. My test was hanging no matter what Task continuation option I seemed to use. Finally I took out ", token, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler);" and replaced it with ", TaskContinuationOptions.OnlyOnRanToCompletion);" Not sure why that worked, but I'm in business. – pStan Jan 22 '15 at 19:02

0 Answers0