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

时间:2011-05-13 14:20:03

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

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

我有一个任务A,我想在完成一系列其他任务(B,C,D等)之前完成任务。因此,我想创建任务B,C,D等作为任务A的延续。 但是,我想将一个'state'对象传递给任务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),它允许我将'state'对象传递给continuation任务。怎么办呢?

注意:

  1. 在创建taskA
  2. 时,我没有taskB的'state'对象
  3. taskB的'state'对象不是taskA
  4. 的输出(返回值)

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

3 个答案:

答案 0 :(得分:22)

最简单的方法可能就是在传递给Func<Task, TResult>的{​​{1}}中捕获它。例如:

ContinueWith

就我个人而言,我发现捕捉状态比攻击状态更容易。

答案 1 :(得分:1)

你做不到。他们希望你使用封闭的力量。只需在循环内定义一个额外的变量来捕获该闭包的当前值。有关捕获和关闭的更多详细信息,请See this answer from Jon Skeet

更新:或者Jon Skeet可以打败我,直接回复您的问题,说完全相同的事情。 :)

答案 2 :(得分:0)

对于以后的读者来说,ContinueWith()函数(至少在.NET 4.7中)具有重载功能,可让您传递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);

有关更多详细信息,请参见this MSDN article