3

I am trying to schedule a function call for a sequence of items using Task parallel library.

The following does not work

List<Task> tasks = new List<Task>();

foreach(var someValue in aCollection)
{
   var t = Task.Factory.StartNew(() => DoSomeWork(someValue));
   tasks.Add(t);
}

Task.WaitAll(tasks.ToArray());

But the below works

Task.WaitAll(aCollection.Select(a => Task.Factory.StartNew(() => DoSomeWork(a))).ToArray());

For the first approach it executes once and then stops. I am not sure if its overwriting the reference or something. Can someone pls. explain?

Also is there a way to pass some sequence number to Task that can be used to identifiy which task was scheduled first. I mean I want to wait for all the tasks to complete but then order the results based on the sequence in the collection.

Jeff LaFay
  • 12,882
  • 13
  • 71
  • 101
stackoverflowuser
  • 22,212
  • 29
  • 67
  • 92

1 Answers1

5

I don't know if this is causing execution to stop, but perhaps it's because you're closing over the loop variable here:

DoSomeWork(someValue));

You need to create a local variable and assign someValue to it, and then use that local variable, as is described in my linked question, like so:

foreach(var someValue in aCollection)
{
   var localCopy = someValue;

   var t = Task.Factory.StartNew(() => DoSomeWork(localCopy));
   tasks.Add(t);
}

Again, I've no idea if that is the problem to your deadlock issue, but that is one issue that will most likely cause problems.

Community
  • 1
  • 1
  • Yes. That was the issue. Thanks. +1. How about the sequence thing? Any idea? – stackoverflowuser Feb 08 '11 at 00:00
  • 1
    You can just use a `for` loop in conjunction with [this overload of Task](http://msdn.microsoft.com/en-us/library/dd235693.aspx). The `object` passed in gets assigned to [AsyncState](http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.asyncstate.aspx), and can be anything, it's completely arbitrary. In this case, just pass in the iterator variable (`i`) and retrieve it when `WaitAll` exits. –  Feb 08 '11 at 00:05
  • An example would really help. Thanks. – stackoverflowuser Feb 08 '11 at 01:31
  • Wait, your second question, I read it more carefully, do you mean you want to know which task was _started_ first, or which one _ended_ first? –  Feb 08 '11 at 01:54