4

我有一个Task<T> t1. 我想在完成Task t2后运行另一个t1。我选择使用的.ContinueWith方法t1

void ThenFrob(Task<Frobber> t1) {
    t1.ContinueWith(frobber => frobber.Frob())
}

除了,我不能这样做,因为 Action 参数Task<T>传递的是Task<T>,而不是T它本身。相反,我必须将传递给我的操作的参数的结果与它进行交互。

void ThenFrob(Task<Frobber> t1) {
    t1.ContinueWith(frobberTask => {
        var frobber = frobberTask.Result;
        frobber.frob();
    });
}

如果 ContinueWith 的目的是向链中添加另一个动作,那么语言设计者为什么不简单地传递上一个任务的结果呢?或者,在非泛型任务的情况下,期望一个无参数的动作?

4

1 回答 1

3

当任务进入task.IsCompleted == true状态时,ContinueWith 运行委托。不是当它进入task.IsCompleted == true && task.IsFaulted == false && task.IsCanceled == false状态时,抛出异常的任务或被取消的任务都“完成”但不会产生结果。

您可以传入一些重载,以获得TaskContinuationOptionsTaskContinuationOptions.OnlyOnRanToCompletion所描述的行为,但是对于单个枚举选项进行重载会更复杂,Action<T>因此它们只使用一般重载,Action<Task<T>>因此您可以使用相同的方法,如果您是正在做OnlyOnRanToCompletion,或者如果你正在做OnlyOnFaulted

此外,已完成任务的对象中仍有有用的信息Task,如果您使用该AsyncState属性传递元数据,如果未将已完成的任务传递给ContinueWith您,则除非您使用变量捕获兰巴达表达。

于 2016-03-10T21:13:04.937 回答