Захваченные переменные в потоке в цикле в 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.)

Другие вопросы по тегам