如何将状态对象传递给延续任务



>我正在使用带有 C# 的 .NET 4.0 任务并行库(我第一次使用 TPL)

我有一个任务 A,我想在启动一堆其他任务(B、C、D 等)之前运行完成。因此,我想创建任务 B、C、D 等作为任务 A 的延续。但是,我想将一个"状态"对象传递给任务 B,将另一个状态对象传递给任务 C,依此类推。

我可以通过简单地使用采用状态对象的 Task 构造函数重载将状态对象传递给任务 A,例如 http://msdn.microsoft.com/en-us/library/dd783035.aspx 描述此 Task 构造函数重载:

Task(Action<Object>, Object, CancellationToken) 

这工作正常,第二个参数是我的"状态"对象。

我想创建一个延续任务,例如为任务 B:

Task taskB = taskA.ContinueWith(/* args here*/)

但是,我看不到 ContinueWith() 重载(见 http://msdn.microsoft.com/en-us/library/dd235663.aspx),它允许我将"状态"对象传递给延续任务。如何做到这一点?

笔记:

  1. 在创建任务 A 时,我没有可用的任务 B 的"状态"对象
  2. 任务 B 的"状态"对象不是任务 A 的输出(返回值)

对于某些上下文,我正在做的是在几个循环中创建任务B,taskC等,因此我使用状态对象将循环变量的值传递给taskB,taskC等,以避免总是以任务中循环变量的最终值结束的问题(闭包问题)。

最简单的方法可能是简单地在你传递到ContinueWith Func<Task, TResult>中捕获它。例如:

object taskBState = GetStateHere();
Task taskB = taskA.ContinueWith(task => RealContinuation(task, taskBState));

就我个人而言,我发现捕获这样的状态比无论如何都传递状态更容易。

你不能。他们希望你使用闭包的力量。只需在循环中定义一个附加变量即可捕获该闭包的当前值。请参阅Jon Skeet的答案,了解有关捕获和关闭的更多详细信息。

更新:或者乔恩·斯基特可以打败我,直接回答你的问题,说完全相同的话。 :)

对于将来的读者,至少在 .NET 4.7 中,ContinueWith()函数具有允许传递state参数的重载:

public System.Threading.Tasks.Task ContinueWith(
  Action<System.Threading.Tasks.Task,object> continuationAction, object state,
  System.Threading.CancellationToken cancellationToken, 
  System.Threading.Tasks.TaskContinuationOptions continuationOptions, 
  System.Threading.Tasks.TaskScheduler scheduler);

有关更多详细信息,请参阅此 MSDN 文章。

最新更新