TaskScheduler ts= TaskScheduler.FromCurrentSynchronizationContext();
try
{
Task<T> task1 = ...
task1.ContinueWith(t =>
{
...
Task<T> task2 = ...
task2.ContinueWith(u =>
{
...
Task<T> task3 = ...
task3.ContinueWith(w =>
{
...
}, new CancellationToken(), TaskContinuationOptions.OnlyOnRanToCompletion, ts);
}, new CancellationToken(), TaskContinuationOptions.OnlyOnRanToCompletion, ts);
}, new CancellationToken(), TaskContinuationOptions.OnlyOnRanToCompletion, ts);
}
catch(Exception)
{
MessageBox.Show("...");
}
您好。我有一些代码(如上所述)。这对我不起作用。我有三个任务在服务器端工作但修改UI,因此所有这些任务都应该在UI线程中生成。更重要的是:如果第二个完成失败,第三个任务不能运行,第二个任务无法运行,除非第一个成功完成。因此,如果第一个以失败告终,我的任务树应该抛出异常并打破其余的操作。如何以最简单的方式实现这一目标?
更新
现在我的代码看起来像
private async void SomeMethod()
{
...
try
{
var r1 = await Method1(...);
var r2 = await Method2(...);
var r3 = await Method3(...);
}
catch
{
MessageBox.Show("...");
}
}
private Task<...> Method1(...)
{
Task<...> task = Task<...>.Factory.StartNew(() =>
{
...
try
{
// Result is null (but that's ok) so 'index out of range exception' is thrown
// It calls my method MyException with this exception (but I don't know in
// which thread and how to catch this (shouldn't be catch by async SomeMethod?)
result = ....Results[0];
}
catch (Exception ex)
{
MyException(ex);
}
return result;
});
return task;
}
public void MyException(Exception ex)
{
throw ex;
}
但我仍然无法捕捉异常。
修改 解决了。我没有捕获异常(只在Method1中忽略)和:
var r1 = await Method1(...);
if(r1!=null)
{
var r2 = await Method2(...);
var r3 = await Method3(...);
}
else
{
...do sth instead of catching ex
}
答案 0 :(得分:4)
最简单的选择是在这里使用await
,因为它将提供您想要的错误处理语义,只需要很少的努力;允许您编写代码,就像它是常规同步代码一样:
try
{
var firstResult = await SomethingAsync();
var secondResult = await SomethingElseAsync(firstResult);
var finalResult = await AnotherThingAsync(secondResult);
}
catch
{
//handle an exception thrown by any of the above async operations.
}
如果你不能这样做(由于在.NET 4.0上),那么你可以使用here描述的Then
方法来获得你想要的语义:
var finalTask = SomethingAsync()
.Then(firstResult => SomethingElseAsync(firstResult))
.Then(secondResult => AnotherThingAsync(secondResult));
finalTask.ContinueWith(t => HandleError(t.Exception),
TaskContinuationOptions.OnlyOnFaulted);
Then
本质上是对ContinueWith
的调用,但具有不同的错误处理语义。如果正在继续的任务抛出异常,则Then
只传播该异常,而不是运行延续。 ContinueWith
只运行延续并吞下异常。