Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

multithreading behavior strange C#!

this is my app to excute a threading example, but the output is not as expected , anyone have any clue about that please

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace OTS_Performence_Test_tool
{
    class Program
    {

        static void testThread(string    xx)
        {

            int count = 0;
            while (count < 5)
            {
                Console.WriteLine(xx );
                count++;

            }
        }

        static void Main(string[] args)
        {
            Console.WriteLine("Hello to the this test app ---");

            for (int i = 1; i<=3; i++)
            {

                    Thread thread = new Thread(() => testThread("" + i + "__"));

                thread.Start();

            }


            Console.ReadKey();
        }
    }
}

but the out but is

3__

3__

3__

3__

3__

3__

3__

3__

3__

3__

4__

4__

4__

4__

4__

what happens exactly anyone can explain please thanks

like image 617
Maadh Avatar asked Nov 11 '14 09:11

Maadh


3 Answers

See Eric Lippert's excellent blog post on this issue.

This is being caused by access to a "modified closure".

Change your loop's body to this:

for (int i = 1; i<=3; i++)
{
    int j = i;  // Prevent use of modified closure.
    Thread thread = new Thread(() => testThread("" + j + "__"));

    thread.Start();
}

(Note that for a foreach loop, this was fixed in .Net 4.5, but it was NOT fixed for a for loop.)

like image 51
Matthew Watson Avatar answered Oct 17 '22 04:10

Matthew Watson


Closure. You must pretty much copy the variable in the thread for it to keep the current value,.

Wight now all threads read the variable i with whatever value they have at the moment they run - NOT with the value it had when thread.start was called for them.

like image 4
TomTom Avatar answered Oct 17 '22 02:10

TomTom


testThread is not called when you create the Thread objects within the for loop - the method is called whenever the thread is scheduled to run. And that might happen later.

In your case, the threads started running after the for loop ended - by that time, i was equal to 3. So testThread was invoked 3 times with the value 3.

like image 1
dcastro Avatar answered Oct 17 '22 03:10

dcastro