dcsimg
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6

Thread: Stopping thread gracefully

  1. #1
    Join Date
    Jul 2002
    Posts
    787

    Stopping thread gracefully

    I have a thread started using this way, and ThreadFunc keep sending data to a serial port.

    Code:
       ThreadStart l_startThread = new ThreadStart(ThreadFunc);
                Thread myThread = new Thread(l_startThread);
                myThread.Start();
    
       
     public void ThreadFunc()    
    {
    
         //writing to com port for as long as it wants
    }
    My problem is how to stop and restart this thread? I can use myThread.Abort(), but i read that this is not a graceful way to stop a thread.

    I tried the following :- (but object disposed exception is thrown) or sometimes my pc application just got hanged when i step through the followings.

    myThread.Interrupt();
    myThread.Join();

    I want to be able to stop and restart the thread above (which send data to COM port constinuously, until the user decided to stop the thread.

  2. #2
    Join Date
    Sep 2008
    Location
    Netherlands
    Posts
    865

    Re: Stopping thread gracefully

    thread.Interrupt will not work:
    "Thread.Interrupt Method: Interrupts a thread that is in the WaitSleepJoin thread state"

    I would use the abort method
    Code:
    private ThreadStart l_startThread = new ThreadStart(ThreadFunc);
    private Thread myThread;
    
    public void StartThread(){
      myThread = new Thread(l_startThread);
      myThread.Start();
    }
    
    public void StopThread(){
      if (myThread != null)
        myThread.Abort();
    }
    
       
    public void ThreadFunc() {
         //writing to com port for as long as it wants
    }

  3. #3
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,116

    Re: Stopping thread gracefully

    Quote Originally Posted by dannystommen View Post
    thread.Interrupt will not work:
    "Thread.Interrupt Method: Interrupts a thread that is in the WaitSleepJoin thread state"

    I would use the abort method
    Thread abort should be used only in extremely rare cases (typically when there is NO other possible way, and you need to hard tear down the entire application.

    The right way to do this is to have a communication method with the thread. This can be as simple as a synchronization object.
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  4. #4
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940

    Re: Stopping thread gracefully

    ...to follow on from CPUWiz's answer, try something like this :

    Code:
    class MyThreadClass
    {
        ManualResetEvent _stopEvent;
        Thread _thread;
    
        public MyThreadClass()
        {
        }
    
        public void Start()
        {
            _stopEvent = new ManualResetEvent(false);
            _thread = new Thread(new ThreadStart(ThreadFunction));
            _thread.Start();
        }
    
        public void Stop()
        {
            _stopEvent.Set();
            _thread.Join();  // block until thread completed          
        }
    
        private void ThreadFunction()
        {
            int index = 0;
    
            while (!_stopEvent.WaitOne(0))
            {
                Thread.Sleep(500);
                Console.WriteLine("{0}", index);
                ++index;
            }
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            MyThreadClass example = new MyThreadClass();
            example.Start();
    
            Thread.Sleep(10000);
    
            example.Stop();
        }
    }
    The manual reset event is used to signal the thread that it should finish (i.e. just return from the thread function).

    Alternatively you can use ansynchronous invocation of delegates to do the business :

    Code:
    class Program
    {
        delegate void ThreadFunctionHandler(ManualResetEvent eventStop);
    
        static void Main(string[] args)
        {
            ManualResetEvent stopEvent = new ManualResetEvent(false);
            ThreadFunctionHandler threadFunction = new ThreadFunctionHandler(ThreadFunction);
            IAsyncResult asyncResult = threadFunction.BeginInvoke(stopEvent, null, null);
            Thread.Sleep(10000);
            stopEvent.Set();
            threadFunction.EndInvoke(asyncResult); // this will block until delegate exits
        }
    
        static void ThreadFunction(ManualResetEvent stopEvent)
        {
            int index = 0;
    
            while (!stopEvent.WaitOne(0))
            {
                Thread.Sleep(500);
                Console.WriteLine("{0}", index);
                ++index;
            }
        }
    }
    Or even use an anonymous method :

    Code:
    class Program
    {
        delegate void ThreadFunctionHandler();
    
        static void Main(string[] args)
        {
            ManualResetEvent stopEvent = new ManualResetEvent(false);
    
            ThreadFunctionHandler threadFunction =
                delegate()
                {
                    int index = 0;
    
                    while (!stopEvent.WaitOne(0))
                    {
                        Thread.Sleep(500);
                        Console.WriteLine("{0}", index);
                        ++index;
                    }
                };
    
            IAsyncResult asyncResult = threadFunction.BeginInvoke(null, null);
            Thread.Sleep(10000);
            stopEvent.Set();
            threadFunction.EndInvoke(asyncResult); // this will block until delegate exits
        }        
    }
    Get the idea ?

    Darwen.

    Darwen.
    www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.

  5. #5
    Join Date
    Jul 2002
    Posts
    787

    Re: Stopping thread gracefully

    Thanks for your code samples!! I love samples.. save me a lot of time figuring it out myself.

    Happy New Year 2009!!!

  6. #6
    Join Date
    Mar 2017
    Posts
    1

    Re: Stopping thread gracefully

    That's great! Assuming you do not have a blocking threadFunction.

    Anytime you receive a deadlock condition accompanied by a cancellation request... none of your examples will resolve this scenario.

    Hence, to kill a thread immediately, abort is used in rare cases such as this. Unfortunately, 'Abort' throws an exception and regardless if you handle it, the exceptions persists. http://stackoverflow.com/questions/5...c-sharp-thread

    This is why I created an parametric polymorphic API that handles this. http://github.com/Latency/ORM-Monitor

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)