Это потому, что переменная nd захвачена в замыкании.Когда потоки запускаются, они все ссылаются на один и тот же экземпляр TreeNode, а именно последний экземпляр, который был назначен nd
.Чтобы исправить это, используйте отдельную переменную, которая не изменяется в области видимости:
foreach (TreeNode nd in tvew.Nodes[0].Nodes)
{
var current = nd;
threadping[index] = new Thread(delegate()
{ this.Invoke(new DelegateClientState(InvokeCheckNetworkState), new object[] {current}); });
Если мы получим технический компилятор, это происходит потому, что компилятор генерирует анонимный класс, содержащий вашу переменную цикла, чтобы сделать егодоступный для потока делегат.Это ожидаемое поведение, хотя, возможно, немного нелогичное, когда вы сталкиваетесь с ним в первый раз.
Для более подробного объяснения замыканий и захвата переменных, см. Раздел «Захваченные переменные» здесьраздел) в статье Джона Скита или этой статьи от Эрика Липперта .Это обычно называется ошибкой «доступа к измененному закрытию».Если вы будете искать этот термин в StackOverflow или Google, вы получите множество обращений, объясняющих его.