Streaming data using lambda expressions

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

      

As expected, the output of the above code is not deterministic as the variable i refers to the same memory location throughout its life cycle. Therefore, each thread calls Console.Write on a variable whose value can change at startup

However

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

      

Also gives a non-deterministic result! I thought the temp variable was local to each iteration of the loop. So each thread grabbed a different memory location and there must have been an np problem.

+3


source to share


4 answers


Your program should have 10 lambdas, each one writing one of the digits 0 through 9 to the console. However, there is no guarantee that the threads will execute in order.



+2


source


Also gives a non-deterministic result!

No, it is not. I checked ten times your first code (repeated the numbers) and the second (didn't).



So everything works fine. As it should be.

+2


source


The second piece of code should be deterministic in the sense that each thread eventually writes its own temp

, and all their rates will be different.

However, this does not guarantee that threads will be scheduled to run in the order they were created. You will see all possible rates, but not necessarily in ascending order.

+1


source


Here is the OP's proof of correctness and both parts of his code are wrong.

And there is also a proof solution.

However, it should be noted that 'non-deterministic' means that streams are receiving the wrong parameter . The order will never be guaranteed.

The code below looks at the OP's second piece of code and demonstrates that it works as expected.

I store the pair (stream id, parameter) and then print it to compare against the stream output to prove that the pairs have not changed. I also added a few hundred milliseconds of random sleep, so the for index should obviously change in those days.

        Dictionary<int, int> hash = new Dictionary<int, int>();
        Random r = new Random(DateTime.Now.Millisecond);
        for (int i = 0; i < 10; i++)
        {
            int temp = i;
            var th = new Thread(() =>
            {
                Thread.Sleep(r.Next(9) * 100);
                Console.WriteLine("{0} {1}", 
                    Thread.CurrentThread.GetHashCode(), temp);
            });

            hash.Add(th.GetHashCode(), temp);

            th.Start();
        }

        Thread.Sleep(1000);
        Console.WriteLine();

        foreach (var kvp in hash)
            Console.WriteLine("{0} {1}", kvp.Key, kvp.Value);

      

+1


source







All Articles