开发者

How can I pass a state object to a continuation task?

开发者 https://www.devze.com 2023-03-06 04:54 出处:网络
I\'m using the .NET 4.0 Task Parallel Library with C# (my first time using TPL) I have a task A which I want to run to completion before firing off a bunch of other tasks (B,C,D, etc). I th开发者_如何

I'm using the .NET 4.0 Task Parallel Library with C# (my first time using TPL)

I have a task A which I want to run to completion before firing off a bunch of other tasks (B,C,D, etc). I th开发者_如何转开发erefore want to create tasks B,C,D etc as continuations of task A. However, I want to pass a 'state' object to task B, another state object to task C, etc.

I can pass a state object to task A by simply using a Task constructor overload that takes a state object, for example http://msdn.microsoft.com/en-us/library/dd783035.aspx describes this Task constructor overload:

Task(Action<Object>, Object, CancellationToken) 

This works fine, and the second argument is my 'state' object.

I want to create a continuation task, e.g. for task B:

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

However, I cannot see a ContinueWith() overload (see http://msdn.microsoft.com/en-us/library/dd235663.aspx) which allows me to pass a 'state' object to a continuation task. How can this be done?

Notes:

  1. I do not have the 'state' object for taskB available at the time I create taskA
  2. The 'state' object for taskB is not an output (return value) of taskA

For some context, what I am doing is creating taskB, taskC, etc. inside a couple of loops and so I am passing the value of the loop variables to taskB, taskC, etc. using a state object, in order to avoid the problem of always ending up with the final value of the loop variables in the tasks (the closure issue).


The simplest approach would probably be to simply capture it in the Func<Task, TResult> you pass into ContinueWith. For example:

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

Personally I find it easier to capture state like that than getting the state passed in anyway.


For future readers, ContinueWith() function, at least in .NET 4.7, has an overload that allows you to pass state parameter:

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);

See this MSDN article for more details.


You can't. They expect you to use the power of closures. Just define an additional variable inside the loops to capture the current value for that closure. See this answer from Jon Skeet for more details on capturing and closures.

Update: Or Jon Skeet could beat me to reply directly to your question saying exactly the same thing. :)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号