在Task中捕获异常的最佳方法是什么?

使用System.Threading.Tasks.Task<TResult>,我必须管理可能引发的异常。我正在寻找做到这一点的最佳方法。到目前为止,我已经创建了一个基类,该基类在调用时管理所有未捕获的异常。.ContinueWith(...)

我想知道是否有更好的方法可以做到这一点。甚至是这样做的好方法。

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

*/

});

}

}

回答:

有两种方法可以执行此操作,具体取决于您所使用的语言版本。

C#5.0以上

您可以使用asyncawait关键字为您简化很多操作。

async并且await被引入该语言以简化使用Task Parallel

Library的工作,从而避免了您必须使用ContinueWith并允许您以自上而下的方式继续编程。

因此,您可以简单地使用try/catch块来捕获异常,如下所示:

try

{

// Start the task.

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

// Await the task.

await task;

}

catch (Exception e)

{

// Perform cleanup here.

}

请注意,封装上述内容的方法 必须 使用已async应用关键字,这样您才可以使用await

C#4.0及以下

您可以使用从枚举中获取值的ContinueWith重载来处理异常,如下所示:TaskContinuationOptions

// Get the task.

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

// For error handling.

task.ContinueWith(t => { /* error handling */ }, context,

TaskContinuationOptions.OnlyOnFaulted);

OnlyOnFaulted该成员TaskContinuationOptions枚举指示应继续 当先行任务抛出异常执行。

当然,您可以有多个调用来ContinueWith取消同一先决条件,从而处理非例外情况:

// Get the task.

var task = new Task<StateObject>(() => { /* action */ });

// For error handling.

task.ContinueWith(t => { /* error handling */ }, context,

TaskContinuationOptions.OnlyOnFaulted);

// If it succeeded.

task.ContinueWith(t => { /* on success */ }, context,

TaskContinuationOptions.OnlyOnRanToCompletion);

// Run task.

task.Start();

以上是 在Task中捕获异常的最佳方法是什么? 的全部内容, 来源链接: utcz.com/qa/412749.html

回到顶部