我想运行这样的东西并等待它,作为一个整体:
Task task1 = Task.Factory.StartNew(() => MethodThatCouldThrow());
Task task2 = task1.ContinueWith(t => HandleFailure(t.Exception),
TaskContinuationOptions.OnlyOnFaulted);
请注意,已经就该主题进行了一些讨论(下面的链接),但他们并没有完全回答这个问题:
如何避免正常情况下的异常处理。正常情况是:
为什么我不能在task2上等待?因为它取消了"取消了"如果task1成功。
为什么我不能在task1上等待?因为它是" Faulted"如果失败(并且task2可能仍在运行)。
为什么我不能等待这两项任务?因为task2是"已取消"如果task1成功,则等待抛出。
一些可能的解决方法(但是它们不符合所需的条件):
我能找到的相关主题:
Waiting on a Task with a OnlyOnFaulted Continuation causes an AggregateException
Using Tasks with conditional continuations
谢谢!
答案 0 :(得分:1)
您应该先等到两个任务完成。 然后使用您喜欢的任何谓词检查任务,并根据它来决定。
您可以通过简单地忽略等待抛出的任何异常(我认为它是脏的,因为它是基于异常的控制流)来等待这两个任务,或者:
var combinedTask = Task.WhenAll(t1, t2);
var combinedTaskNoError = waitTask.ContinueWith(_ => { }, TCO.ExecuteSynchronously);
await combinedTaskNoError; //Will not throw.
该中间行应该可以封装在辅助方法中。我称之为WhenCompleted
。
答案 1 :(得分:1)
使用Task.WhenAll(task1,task2).Wait()
的第一点就足够了。
关于你的第二点,你可以忽略任务2被取消,如此
combinedTask.ContinueWith(_=>{
if (_.IsFaulted){
if (typeof(_.Exception) == typeof(TaskCancelledException){
// Do Nothing
}
}
})
如果你知道task1失败的异常类型,你可以用同样的方式处理它。根据您将任务链接在一起的方式,它只能生成AggregateExceptions,这意味着您需要对InnnerExceptions执行Exception类型检查,直到您到达不属于AggregateException类型的异常