I want to run a class with different value in a thread list. like this :
int index = 0;
foreach (TreeNode nd in tvew.Nodes[0].Nodes)
{
threadping[index] = new Thread(delegate()
{ this.Invoke(new DelegateClientState(InvokeCheckNetworkState), new object[] {nd}); });
threadping[index].Name = nd.Name;
threadping[index].IsBackground = true;
threadping[index].Start();
index++;
}
but when i debug the code, i see that the class parameter is just the last value.
i mean when i go through thread class i see that each time that class run the value of the input parameter is the last value for the last thread.
Can anybody tell me WHY?
It’s because the nd variable is captured in a closure. When the threads run, they are all referencing the same TreeNode instance, namely the last one that was assigned to
nd. To fix, use a separate variable that doesn’t change within the scope:If we get compiler-technical, this happens because the compiler generates an anonymous class containing your loop variable in order to make it accessible for the thread delegate. This is expected behaviour, although maybe a bit counter-intuitive when you run into it the first time.
For a longer explanation of closures and the capture of variables, see the Captured Variables section here (bottom section) in a Jon Skeet article, or this article from Eric Lippert. This is commonly known as an “access to modified closure” bug. If you search for the term on StackOverflow or Google, you will get a lot of hits explaining it.