什么是在任务赶异常的最好方法? [英] What is the best way to catch exception in Task?

查看:150
本文介绍了什么是在任务赶异常的最好方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 System.Threading.Tasks.Task< TResult> ,我要管理可能被抛出的异常。我在寻找做到这一点的最好办法。到目前为止,我已经创建了管理的呼叫内的所有未捕获的异常的基类 .ContinueWith(...)

我不知道是否有更好的方法做呢。或者,即使它是一个很好的方式来做到这一点。

 公共类BaseClass的
{
    保护无效ExecuteIfTaskIsNotFaulted< T>(任务< T> E,行动对行动)
    {
        如果(e.IsFaulted!){行动(); }
        其他
        {
            Dispatcher.CurrentDispatcher.BeginInvoke(新动作(()=>
            {
                / *我显示一个窗口说明在GUI的错误
                 *我记录错误。
                 * /
                this.Handle.Error(e.Exception);
            }));
        }
    }
}

公共类ChildClass:BaseClass的
{
    公共无效DoItInAThread()
    {
        VAR上下文= TaskScheduler.FromCurrentSynchronizationContext();
        Task.Factory.StartNew&其中; StateObject>(()=> this.Action())
                    .ContinueWith(E => this.ContinuedAction(E),上下文);
    }

    私人无效ContinuedAction(任务< StateObject> E)
    {
        this.ExecuteIfTaskIsNotFaulted(即()=>
        {
            / *动作执行
             *我做的东西跟e.Result
             * /

        });
    }
}
 

解决方案

您可以使用处理异常的 ContinueWith 重载这需要从<一个值href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskcontinuationoptions.aspx"><$c$c>TaskContinuationOptions枚举,像这样:

  //获取任务。
VAR任务= Task.Factory.StartNew&LT; StateObject&GT;(()=&GT; {/ *行动* /});

//错误处理。
task.ContinueWith(T =&GT; {/ *错误处理* /},环境,
    TaskContinuationOptions.OnlyOnFaulted);
 

TaskContinuationOptions 枚举的 OnlyOnFaulted 成员表示继续应的只有的是如果执行的前提任务抛出异常。

当然,你也可以有多个呼叫 ContinueWith 过相同的前提,处理非特殊情况:

  //获取任务。
VAR任务= Task.Factory.StartNew&LT; StateObject&GT;(()=&GT; {/ *行动* /});

//错误处理。
task.ContinueWith(T =&GT; {/ *错误处理* /},环境,
    TaskContinuationOptions.OnlyOnFaulted);

//如果成功。
task.ContinueWith(T =&GT; {/ *成功* /},环境,
    TaskContinuationOptions.OnlyOnRanToCompletion);
 

With System.Threading.Tasks.Task<TResult>, I have to manage the exceptions that could be thrown. I'm looking for the best way to do that. So far, I've created a base class that manages all the uncaught exceptions inside the call of .ContinueWith(...)

I'm wondering if there's a better way do do that. Or even if it is a good way to do that.

public class BaseClass
{
    protected void ExecuteIfTaskIsNotFaulted<T>(Task<T> e, Action action)
    {
        if (!e.IsFaulted) { action(); }
        else
        {
            Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
            {
                /* I display a window explaining the error in the GUI 
                 * and I log the error.
                 */
                this.Handle.Error(e.Exception);
            }));            
        }
    }
}   

public class ChildClass : BaseClass
{
    public void DoItInAThread()
    {
        var context = TaskScheduler.FromCurrentSynchronizationContext();
        Task.Factory.StartNew<StateObject>(() => this.Action())
                    .ContinueWith(e => this.ContinuedAction(e), context);
    }

    private void ContinuedAction(Task<StateObject> e)
    {
        this.ExecuteIfTaskIsNotFaulted(e, () =>
        {
            /* The action to execute 
             * I do stuff with e.Result
             */

        });        
    }
}

解决方案

You can handle exceptions using the ContinueWith overload that takes a value from the TaskContinuationOptions enumeration, like so:

// Get the task.
var task = Task.Factory.StartNew<StateObject>(() => { /* action */ });

// For error handling.
task.ContinueWith(t => { /* error handling */ }, context,
    TaskContinuationOptions.OnlyOnFaulted);

The OnlyOnFaulted member of the TaskContinuationOptions enumeration indicates that the continuation should only be executed if the antecedent task threw an exception.

Of course, you can have more than one call to ContinueWith off the same antecedent, handling the non-exceptional case:

// Get the task.
var task = Task.Factory.StartNew<StateObject>(() => { /* action */ });

// For error handling.
task.ContinueWith(t => { /* error handling */ }, context, 
    TaskContinuationOptions.OnlyOnFaulted);

// If it succeeded.
task.ContinueWith(t => { /* on success */ }, context,
    TaskContinuationOptions.OnlyOnRanToCompletion);

这篇关于什么是在任务赶异常的最好方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆