WPF任务/线程错误陷阱和TaskContinuation选项无法按预期工作

时间:2015-01-21 22:39:51

标签: c# wpf multithreading task

我有几个使用Task.Factory.StartNew启动的链式任务(...

经过一些严重的疼痛,他们运行得很好。现在我要回去尝试为Tasks添加更好的错误检查,因为这是让任务正常工作的痛苦。

我创建了一个小型WPF应用程序,仅用于测试一项任务并尝试捕获错误。我有这个作为“最后的度假胜地”的错误陷阱。

TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;

但是,我想在此之前捕获错误并尝试优雅地处理它们。

测试这个小任务:

        Task[] tasks = new Task[1];

        MessageBox.Show("Before Tasks");

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

            }
            , token, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler);

后台任务如下(一行测试成功,另一行测试失败。注释取决于我正在处理的内容):

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

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

我在任务StartNew之后进行等待和错误检查只是为了暂停并允许我在进入TaskScheduler_UnobservedTaskException之前捕获错误

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

我可能误解了处理任务/线程错误的正确方法,但这是我的问题:

1)当我使用除None之外的任何其他任务继续选项时。我的ContinueWith代码未执行。我真的想在取消/故障/没有跑完成时做点什么。

2)不确定task.Wait()和TaskContinuation方法是否是陷阱和处理错误的最佳方法,但我找不到另一种方法。

3)我想链接我的任务延续选项。例如。处理OnlyOnRanToCompletion的代码片段和处理NotOnRanToCompletion的另一部分。我似乎无法让他们一起工作。

简而言之,使用taskContinuationOptions.None以及task.Wait()之外的任何东西,catch aggregateexception似乎都有效。

所有其他的悬念......

我是这样做错的?

谢谢!

更新 - 此作品:

        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;
                }
            }
            );

似乎就像我做的那样。继续关闭主要任务的StartNew它似乎不能很好地工作。当我创建第二个任务时,使用.ContinueWith创建第一个任务...我们正在开展业务。我真的不明白其中的区别。看起来他们都应该工作。

0 个答案:

没有答案