我有Task<T> t1
。我想在Task t2
完成后运行另一个t1
。我选择使用.ContinueWith
的{{1}}方法。
t1
除此之外,我不能这样做,因为void ThenFrob(Task<Frobber> t1) {
t1.ContinueWith(frobber => frobber.Frob())
}
的Action参数是Task<T>
而不是Task<T>
本身。相反,我必须将传递给我的动作的参数的结果与它进行交互。
T
如果ContinueWith的意思是向链添加另一个动作,为什么语言设计者不会简单地传递上一个任务的结果?或者,在非通用任务的情况下,期望无参数动作?
答案 0 :(得分:2)
当任务进入task.IsCompleted == true
状态时,ContinueWith运行委托。不是当它进入task.IsCompleted == true && task.IsFaulted == false && task.IsCanceled == false
状态时,抛出异常的任务或被取消的任务都会“完成”,但不会产生结果。
您可以通过TaskContinuationOptions
传递重载,例如TaskContinuationOptions.OnlyOnRanToCompletion
来获取您所描述的行为,但是对于单个枚举选项而言,Action<T>
重载会更复杂因此,他们只使用Action<Task<T>>
的一般重载,因此如果您正在执行OnlyOnRanToCompletion
或正在执行OnlyOnFaulted
,则可以使用相同的方法。
如果您使用AsyncState
属性传递元数据,如果已完成的任务未传递给{{1},则完成任务的Task
对象中仍然存在有用的信息除非你使用lambada表达式的变量捕获,否则你无法获得那些数据。