Search code examples
c#multithreadingfor-loopclosurescaptured-variable

Captured variables in a thread in a loop in C#, what is the solution?


I came across this example that demonstrates the case of Captured Variables within a Thread and a loop :

Code 1

for (int i = 0; i < 10; i++)
{
   new Thread(() => Console.Write(i)).Start();
}

Result 1

0223558779

The suggested solution is said to be creating a temporary variable as follows :

Code 2

for (int j = 0; j < 10; j++)
{
    int temp = j;
    new Thread(() => Console.Write(temp)).Start();
}

Result 2

0124356879

It seems that this solution only eliminates redundancy by using the temp variable which will create 10 different memory locations, yet the sequence is still not ordered, well I understand the reason, which is related to the threads not being too fast executing Console.Write(temp) before iterating and starting the future threads, I tried to slow down the loop by sleeping the main thread giving time to each thread to write properly by doing :

Code 3

for (int i = 0; i < 10; i++)
{
   new Thread(() => Console.Write(i)).Start();
   Thread.Sleep(10);   
}

It resolves the problem, but I don't consider this a real solution when it comes to real scenarios, is there a trick or a practice I'm missing here to show a complete correct sequence like 0123456789 ?


Solution

  • came across this example that demonstrates the case of Captured Variables within a Thread and a loop

    Note C# will have a functional change (in C#6 IIRC): C# will automatically generate separate values to capture (because that is what you always want).

    yet the sequence is still not ordered,

    Of course it isn't. You cannot control the order in which threads are scheduled.

    , is there a trick or a practice I'm missing here to show a complete correct sequence

    You need to reorder the results as the threads complete, or – if the processing is small – don't use threads. (Threads are, on Win32, quite expensive things to create, only use if you are going to do substantive work, and even then the thread pool or Task Parallel Library, TPL, are better options.)