.net - 为什么ContinueWith传Task作为参数

标签 .net task-parallel-library design-decisions

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

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

除了,我不能这样做,因为 Task<T> 的 Action 参数通过 Task<T> ,而不是 T本身。相反,我必须将传递给我的操作的参数的结果与它进行交互。
void ThenFrob(Task<Frobber> t1) {
    t1.ContinueWith(frobberTask => {
        var frobber = frobberTask.Result;
        frobber.frob();
    });
}

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

最佳答案

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

您可以在 TaskContinuationOptions 中传递重载喜欢 TaskContinuationOptions.OnlyOnRanToCompletion获得您所描述的行为,但拥有 Action<T> 会更复杂仅用于单个枚举选项的重载,因此它们仅使用 Action<Task<T>> 的一般重载因此,如果您正在执行 OnlyOnRanToCompletion,则可以使用相同的方法或者如果你正在做 OnlyOnFaulted .

Task 中还有有用的信息。已完成任务的对象,如果您使用 AsyncState 如果已完成的任务未传递给 ContinueWith,则传递元数据的属性除非您使用 lambda 表达式的变量捕获,否则您将无法获取该数据。

关于.net - 为什么ContinueWith传Task作为参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35927191/

相关文章:

c# - 具有 IEnumerable 关系类型的 Autofac 键控服务

c# - 使用 Parallel.ForEach 时如何发送进度

.net - TPL 数据流(TDF)和响应式扩展有什么区别?

c# - 需要数组的可变参数函数的设计决策是什么?

c# - 为什么存储局部变量并读回它会触发 TargetInvocationException?

c# - SMTP 友好名称在 3 个不同的地方——仍然没有显示

c# - Asp.Net MVC 5 - 长时间运行的任务 - 如何确保 IIS 回收 AppPool 时工作线程不会被丢弃?

asp.net - 如何为新项目决定使用 WebForms 还是 ASP.NET MVC 3?

c# - WCF 服务问题仅在生产中返回较大的对象时