【问题标题】:How can I pass a state object to a continuation task?如何将状态对象传递给延续任务?
【发布时间】:2011-05-13 14:20:03
【问题描述】:

我正在使用带有 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. 在我创建 taskA 时,我没有 taskB 的“状态”对象
  2. taskB 的“状态”对象不是 taskA 的输出(返回值)

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

【问题讨论】:

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


    【解决方案1】:

    最简单的方法可能是在您传递给ContinueWithFunc&lt;Task, TResult&gt; 中简单地捕获它。例如:

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

    我个人发现捕获这样的状态比获取状态更容易。

    【讨论】:

    • 感谢您的快速回复。我在测试程序中尝试了您的建议,效果很好。我知道我需要提高对闭包的理解......是的,这确实是一种更简单的捕获状态的方式......
    • 不幸的是,在意识到带有闭包的长延续链中的一些性能影响与状态参数之后,MS 改变了主意(link)。您可以编写适用于 4.0 和 4.5 的代码,但不会利用 4.5 中的显着性能改进;或者编写带有显式参数且没有闭包的 4.5 特定代码。
    【解决方案2】:

    你不能。他们希望您使用闭包的力量。只需在循环内定义一个附加变量即可捕获该闭包的当前值。 See this answer from Jon Skeet 了解有关捕获和关闭的更多详细信息。

    更新: 或者 Jon Skeet 可以击败我直接回答你的问题,说完全一样的话。 :)

    【讨论】:

      【解决方案3】:

      对于未来的读者,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

      【讨论】:

        猜你喜欢
        • 2017-03-08
        • 2019-06-25
        • 2019-10-27
        • 2015-04-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-05
        相关资源
        最近更新 更多