Click here to Skip to main content
15,909,242 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
why in first code the compiler reach to end loop ,but the second cannot ???

First:
class Program
{
    static bool Mark = true;

    static void Main(string[] args)
    {
        Program pro = new Program();

        Thread ob = new Thread(TestThread);
        ob.Start();

        Thread.Sleep(20);

        Mark = false;
        Console.WriteLine("End prog");

    }
    static void TestThread()
    {
        Console.WriteLine("start loop");
        while (Mark) { }
        Console.WriteLine("End loop");
    }
}

second:
class Program
    {
        bool Mark = true;

        static void Main(string[] args)
        {
            Program pro=new Program();
            
            Thread ob = new Thread(TestThread);
            ob.Start(pro);

            Thread.Sleep(20);

            pro.Mark = false;
            Console.WriteLine("End prog");

        }
        static void TestThread(object o)
        {
            Program X = (Program)o;
  
            Console.WriteLine("start loop");
            while (X.Mark){ }
            Console.WriteLine("End loop");
        }        
    }
Posted

1 solution

Of course, both variants will work, and the thread reaches "End loop". You just used parameter of the Thread.Start to pass the class instance needed to work with the instance variable. Yes, I tested it, just in case.

Nevertheless, such kind of coding is a huge abuse of threading. First of all, you should never use any shared variables (Mark in both your cases) without synchronization, which could be a simple lock:
http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx[^].

However, I understand that you do it just for the purposes of study, which is actually a good thing. But you should understand the abuse.

Even though what you do with ParametrizedThreadStart is a common practice, I think this is lame. Who told you that the thread method (TestThread, in your case) should be a static method? (I know, MSDN documentation may look unclear at this point.) This is not C++. And, as you can use an instant method, you can pass whatever you need through "this". It will eliminate the need for type case, which is of course potentially dangerous. All you need to do is to wrap a thread. It gives a lot of other benefits, really important ones. Please see my past answers:
How to pass ref parameter to the thread[^],
Change parameters of thread (producer) after it is started[^],
MultiThreading in C#[^],
AsyncCallback and Threadings[^].

Also, look at your while (X.Mark) { }. This is called spin wait, a really bad thing. Do you understand that it simple statement takes 100% of the CPUT (or some CPU core) for a while, doing nothing useful? Usually, people do such dirty work with some more or less arbitrary sleep in the loop. However, this is still not a good solution: if you check up the flag periodically, but rarely, you miss the event where you need to exit the thread, but if you check up frequently, you waste CPU time. There is no real optimum. Ideally, you should do in on hardware interrupt. Is it possible? Yes, in this case, through Thread.Abort:
http://msdn.microsoft.com/en-us/library/system.threading.thread.abort.aspx[^].

However, this can be a really dangerous approach, unless you know very well how it works and how can you use this technique in a save way. Actually, not many understand that. Most members will probably recommend using cooperative approach in all cases, but this is a very complex matter. Anyway, Thread.Abort has nothing to do with old nasty TerminateThread> Please see my past answers where I try to explain that:
Close correcly the thread inside a dll[^],
Problem with creating Process from dedicated thread[^].

Actually, as your TestThread does not do anything at all during wait, you can use wait state through
C#
class Program {

     static ManualResetEvent eventHandle = new ManualResetEvent(false);

     static void Main(string[] args) {
         Program pro = new Program();
         Thread ob = new Thread(pro.TestThread);
         ob.Start();
         Thread.Sleep(2000);
         eventHandle.Set();
         Console.WriteLine("End prog");
     } //Main

     void TestThread() {
         Console.WriteLine("start loop");
         eventHandle.WaitOne();
         Console.WriteLine("End loop");
     } //TestThread

 } // class Program


In practice, however, it makes little sense, because — why would we need a thread which does nothing before exiting, why not exit immediately? Only to write "End loop"? However, this last statement can do something important, so such cases are possible, but relatively rare. The event wait handlers are good for other purposes: to throttle some thread (pause without using deprecated and dangerous Thread.Pause) by using the wait state without using any CPU time. I explained it in these past answers:
pause running thread[^],
ManualResetEvent and AutoResetEvent in Thread[^],
Making Code Thread Safe[^].

—SA
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900