Проблема в том, что переменная i
перехватывается, и к тому моменту, когда поток действительно запускается, это 2.
Используйте это вместо:
for (int i = 0; i < numberOfThreads; i++)
{
int value = x[i];
new Thread(() => DoWork(value)).Start();
}
Или:
foreach (int value in x)
{
int copy = value;
new Thread(() => DoWork(copy)).Start();
}
Или:
for (int i = 0; i < numberOfThreads; i++)
{
int copyOfI = i;
new Thread(() => DoWork(x[copyOfI])).Start();
}
В каждом случае лямбда-выражение будет захватывать новую переменную на каждой итерации цикла - переменную, которая не будет изменяться при последующих итерациях.
В общем, вам следует избегать захвата переменной цикла в лямбда-выражении, которое будет выполнено позже. См. сообщение Эрика Липперта в блоге на эту тему для получения более подробной информации.
Начиная с C # 5, вполне вероятно, что поведение цикла foreach
будет изменено, чтобы избежать этой проблемы, но эквивалент цикла for
все равно будет проблемой.