You haven't shown the loop, and that's crucial. For instance, this is broken:
foreach (Foo myParam in parameters)
{
ThreadStart processTaskThread = delegate { ProcessTasks(myParam ); };
new Thread(processTaskThread).Start();
}
But this is okay:broken:
foreach (Foo myParam in parameters)
{
Foo copy = myParam; // This line is crucial
// Then we use the new variable in the anonymous method
ThreadStart processTaskThread = delegate { ProcessTasks(copy); };
new Thread(processTaskThread).Start();
}
In the first version, the myParam
variable is being captured, and there's only one variable. In the second version, there's a new "instance" of the variable for each iteration of the loop. See my article on closures for more information.
Note that this doesn't require threads to demonstrate the problem. Here's an example without using any thread:
using System;
using System.Collections.Generic;
class Test
{
static void Main()
{
List<Action> actions = new List<Action>();
for (int i=0; i < 10; i++)
{
actions.Add(delegate { Console.WriteLine(i); });
}
foreach (Action action in actions)
{
action();
}
}
}
That prints "10" ten times. Here's the fixed version:
using System;
using System.Collections.Generic;
class Test
{
static void Main()
{
List<Action> actions = new List<Action>();
for (int i=0; i < 10; i++)
{
int copy = i;
actions.Add(delegate { Console.WriteLine(copy); });
}
foreach (Action action in actions)
{
action();
}
}
}