Reputation: 1362
I'm starting with the new .net 4.5 async programming and I found a situation like the code below: I have a sync method but I would like to make several calls and make it run in parallel. However, in this code, all the calls to the sync method runs with the id = 10 and I'm not sure why (probably I misunderstand something with this new approach :).
class Program
{
static void Main(string[] args)
{
var tasks = new List<Task>();
for (int i = 0; i < 10; i++)
{
var foo = new Foo();
var fooTask = Task.Run(() => foo.FooNonAsyncMethod(i));
tasks.Add(fooTask);
}
tasks.ForEach(t => t.Wait());
Console.WriteLine("All Done!");
Console.ReadLine();
}
}
public class Foo
{
public void FooNonAsyncMethod(int id)
{
Console.WriteLine("Starting {0}", id);
Thread.Sleep(4000);
Console.WriteLine("Ending {0}", id);
}
}
// Output:
// Starting 10
// Starting 10
// Starting 10
// Starting 10
// Ending 10
// Starting 10
// Starting 10
// Ending 10
// Ending 10
// ...
Upvotes: 1
Views: 704
Reputation: 1495
That's because there is only 1 variable i
and the lambda expressions bind on a variable and not a value.
You can fix this by using:
for (int i = 0; i < 10; i++)
{
int newI = i;
var foo = new Foo();
var fooTask = Task.Run(() => foo.FooNonAsyncMethod(newI));
tasks.Add(fooTask);
}
As @Yuriy mentioned, this answer has a lot more info on this particularity : Is there a reason for C#'s reuse of the variable in a foreach?
Upvotes: 4