Захваченные переменные в потоке в цикле в C#, каково решение?
Я наткнулся на этот пример, который демонстрирует случай Captured Variables
в пределах Thread
и цикл:
Код 1
for (int i = 0; i < 10; i++)
{
new Thread(() => Console.Write(i)).Start();
}
Результат 1
0223558779
Предполагается, что предлагаемое решение создает временную переменную следующим образом:
Код 2
for (int j = 0; j < 10; j++)
{
int temp = j;
new Thread(() => Console.Write(temp)).Start();
}
Результат 2
0124356879
Кажется, что это решение устраняет избыточность только с помощью temp
переменная, которая создаст 10 различных областей памяти, но последовательность все еще не упорядочена, хорошо я понимаю причину, которая связана с тем, что потоки не выполняются слишком быстро Console.Write(temp)
перед итерацией и запуском будущих потоков я попытался замедлить цикл, спя основной поток, давая каждому потоку время для правильной записи, выполнив:
Код 3
for (int i = 0; i < 10; i++)
{
new Thread(() => Console.Write(i)).Start();
Thread.Sleep(10);
}
Это решает проблему, но я не считаю это реальным решением, когда речь идет о реальных сценариях, есть ли уловка или практика, которую я здесь упускаю, чтобы показать полную правильную последовательность, такую как 0123456789
?
1 ответ
наткнулся на этот пример, который демонстрирует случай захваченных переменных внутри потока и цикла
Примечание. C# будет иметь функциональное изменение (в C#6 IIRC): C# автоматически генерирует отдельные значения для захвата (потому что это то, что вы всегда хотите).
все же последовательность все еще не упорядочена,
Конечно нет. Вы не можете контролировать порядок, в котором запланированы потоки.
Есть ли уловка или практика, которую я пропускаю здесь, чтобы показать полную правильную последовательность
Вам нужно изменить порядок результатов после завершения потоков или - если обработка небольшая - не использовать потоки. (Потоки на Win32 - довольно дорогие вещи для создания, используйте их, только если вы собираетесь выполнять основную работу, и даже тогда лучше использовать пул потоков или Task Parallel Library, TPL.)