【问题标题】:Waiting on one thing for task with conditional continuation等待有条件继续的任务的一件事
【发布时间】:2015-02-19 17:35:02
【问题描述】:

我想运行这样的东西并等待它,作为一个整体:

            Task task1 = Task.Factory.StartNew(() => MethodThatCouldThrow());

            Task task2 = task1.ContinueWith(t => HandleFailure(t.Exception),
                TaskContinuationOptions.OnlyOnFaulted);

请注意,已经有一些关于该主题的讨论(下面的链接),但他们并没有完全回答这个问题:

  1. 如何等待一件事来确保工作完成(*工作被定义为主要任务加上可能的延续)
  2. 如何避免正常情况下的异常处理。正常情况是:

    • task1 完成(RanToCompletion),task2 未运行(Canceled)
    • task1 出错(Faulted),但 task2 成功处理了它(RanToCompletion) (其他情况不正常应该抛出,例如task2故障)

为什么我不能只等待 task2?因为如果 task1 成功,它就会“取消”。

为什么我不能只等待 task1?因为如果它失败了它就是“Faulted”(并且 task2 可能仍在运行)。

为什么我不能同时完成这两个任务?因为如果 task1 成功,则 task2 被“取消”,并且这个等待抛出。

几种可能的解决方法(但它们不满足所需条件):

  • 无条件延续,检查要做什么
  • 有条件的延续但更复杂的等待,例如等待task2,如果task1成功则忽略取消异常。

我能找到的相关主题:

Waiting on a Task with a OnlyOnFaulted Continuation causes an AggregateException

Using Tasks with conditional continuations

谢谢!

【问题讨论】:

  • 你可以等待(或等待)你想要的一切。只需在 try catch 块中执行此操作

标签: c# .net task-parallel-library


【解决方案1】:

对于您的第一点,使用Task.WhenAll(task1,task2).Wait() 就足够了。

至于你的第二点,你可以忽略任务 2 像这样被取消

combinedTask.ContinueWith(_=>{
    if (_.IsFaulted){
        if (typeof(_.Exception) == typeof(TaskCancelledException){
            // Do Nothing
        }
    }
})

如果你知道 task1 失败的异常类型,你可以用同样的方法来处理。根据您将任务链接在一起的方式,它只能产生 AggregateExceptions,这意味着您需要对 InnnerExceptions 进行异常类型检查,直到遇到非 AggregateException 类型的异常

【讨论】:

    【解决方案2】:

    您可能应该先等到两个任务都完成。 然后使用您喜欢的任何谓词检查任务并据此做出决定。

    您可以通过简单地忽略等待引发的任何异常(我认为这很脏,因为它是基于异常的控制流)来等待这两个任务,或者:

    var combinedTask = Task.WhenAll(task1, task2);
    var combinedTaskNoError = combinedTask.ContinueWith(_ => { }, TCO.ExecuteSynchronously);
    
    await combinedTaskNoError; //Will not throw.
    

    中间的那一行可能应该封装在一个辅助方法中。我会称之为WhenCompleted

    【讨论】:

      猜你喜欢
      • 2020-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-15
      • 2020-07-14
      • 2012-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多