【发布时间】:2013-01-31 16:41:17
【问题描述】:
假设以下同步代码:
try
{
Foo();
Bar();
Fubar();
Console.WriteLine("All done");
}
catch(Exception e) // For illustration purposes only. Catch specific exceptions!
{
Console.WriteLine(e);
}
现在假设所有这些方法都有一个 Async 对应方法,并且出于某种原因我必须使用它们,所以简单地将整个东西包装在一个新任务中不是一种选择。
我将如何实现相同的行为?
我所说的“相同”是:
- 如果抛出异常,则执行异常处理程序。
- 如果抛出异常,则停止执行以下方法。
我唯一能想到的是可怕:
var fooTask = FooAsync();
fooTask.ContinueWith(t => HandleError(t.Exception),
TaskContinuationOptions.OnlyOnFaulted);
fooTask.ContinueWith(
t =>
{
var barTask = BarAsync();
barTask.ContinueWith(t => HandleError(t.Exception),
TaskContinuationOptions.OnlyOnFaulted);
barTask.ContinueWith(
t =>
{
var fubarTask = FubarAsync();
fubarTask.ContinueWith(t => HandleError(t.Exception),
TaskContinuationOptions.OnlyOnFaulted);
fubarTask.ContinueWith(
t => Console.WriteLine("All done"),
TaskContinuationOptions.OnlyOnRanToCompletion);
},
TaskContinuationOptions.OnlyOnRanToCompletion);
},
TaskContinuationOptions.OnlyOnRanToCompletion);
请注意:
- 我需要一个适用于.NET 4 的解决方案,所以
async/await是不可能的。但是,如果它可以与async/await一起使用,请随时展示如何。 - 我不需要使用 TPL。如果 TPL 不可能,另一种方法也可以,也许使用 Reactive Extensions?
【问题讨论】:
-
不认为有可能编写一个辅助方法,它接受一个
params Action[]参数以及一个完整/错误处理程序,它从中为您构建所有这些讨厌的东西? -
@ChrisSinclair:好主意。如果没有“真正的”解决方案,这就是我要做的……
-
您还需要为每个任务添加一个延续来处理
Canceled,如果有任何任务是可取消的。 -
@Servy:假设它们不能被取消。
-
@ChrisSinclair 这不是
Action[],而是Task[]。基本上是一个包含异常处理的ForEachAsync。
标签: c# .net .net-4.0 task-parallel-library