How to stop threads?

前端 未结 6 1029
清酒与你
清酒与你 2021-01-23 07:45

Hi guys I start threads with such code:

    Thread[] thr;
    private void button1_Click(object sender, EventArgs e)
    {
        decimal value = numericUpDown2         


        
相关标签:
6条回答
  • 2021-01-23 08:22

    You can use a CancellationToken to signal when the operation should stop.

    1. Create a CancellationTokenSource as an instance field of your type that you initialize in the button click handler.

    2. In your background method periodically check the IsCancellationRequested property of the Token in the token source, or call ThrowIfCancellationRequested() if you want it to just throw an exception if it is canceled.

    3. When you want to stop the threads call Cancel on the token source.

    0 讨论(0)
  • 2021-01-23 08:24

    If you want to know how to terminate the thread gracefully, I'd recommend you to take a look the following example on MSDN:

    using System;
    using System.Threading;
    
    public class Worker
    {
        public void DoWork()
        {
            while (!_shouldStop)
            {
                Console.WriteLine("worker thread: working...");
            }
            Console.WriteLine("worker thread: terminating gracefully.");
        }
        public void RequestStop()
        {
            _shouldStop = true;
        }
        // Volatile is used as hint to the compiler that this data
        // member will be accessed by multiple threads.
        private volatile bool _shouldStop;
    }
    
    public class WorkerThreadExample
    {
        static void Main()
        {
            Worker workerObject = new Worker();
            Thread workerThread = new Thread(workerObject.DoWork);
            workerThread.Start();
            Console.WriteLine("main thread: Starting worker thread...");
    
            while (!workerThread.IsAlive); // Loop until worker thread activates
    
            // Put the main thread to sleep for 1 millisecond to
            // allow the worker thread to do some work:
            Thread.Sleep(1);
    
            workerObject.RequestStop();
    
            // Use the Join method to block the current thread 
            // until the object's thread terminates.
            workerThread.Join();
            Console.WriteLine("main thread: Worker thread has terminated.");
        }
    }
    
    0 讨论(0)
  • 2021-01-23 08:32

    This is Windows Form Code in which:

    • 1) On Clicking start button, Main Thread creates another Thread
    • 2) Again created Thread creates on more Thread.
    • 3) On clicking Stop button, First the last Thread should terminate Then the Thread created by Main thread should Terminate.

      namespace Thread_TerminateProblem
      {    
          public partial class Form1 : Form
          {     
      
      
          private static AutoResetEvent m_ResetEvent = null;                
          private static ManualResetEvent m_ResetEvent_Thread = new ManualResetEvent(false);
          enum ServiceState { Start, Stop };
          bool flag = false;
          int x = 0;
          ServiceState _state;
          public Form1()
          {
              InitializeComponent();
          }
      
          private void btnStart_Click(object sender, EventArgs e)
          {
              flag = true;
              _state = ServiceState.Start;
              m_ResetEvent = new AutoResetEvent(true);            
              Thread t1 = new Thread(fun_Thread1);
              t1.Start();
              t1.Name = "Thread1";            
          }
      
          private void btnStop_Click(object sender, EventArgs e)
          {
              _state = ServiceState.Stop;
              m_ResetEvent.Set();           
          }
      
      
          private void fun_Thread1()
          {
              while (true)
              {                               
                  m_ResetEvent.WaitOne();                
                  switch (_state)
                  {
                      case ServiceState.Start:
                          {                            
                              Thread t = new Thread(fun_Thread2);
                              t.Start();
                              t.Name = "Thread2";
                              break;
                          }
                      case ServiceState.Stop:
                          {
                              m_ResetEvent_Thread.Set();
                              flag = true;
                              break;
                          }
                  }
                  // When the child Thread terminates, Then only this thread should terminate
                  if (flag == true)
                  {
                      // Waiting for notification from child Thread
                      notifyParent.WaitOne();
                      Thread.Sleep(100);
                      break;
                  }                
                  m_ResetEvent.Reset();                              
              }            
          }
      
          private static ManualResetEvent notifyParent = new ManualResetEvent(false);
      
          private void fun_Thread2()
          {
              while (true)
              {
                  if (m_ResetEvent_Thread.WaitOne(1, false))
                  {
                      notifyParent.Set();
                      break;
                  }
                  x++;                
              }
          }     
      }
      

      }

    0 讨论(0)
  • 2021-01-23 08:32

    simplistic answer is to use the thread Abort() method however your code does not really make it clear what condition,

    what loop tests vs a condition? why do you need to abort a thread? I am asking as there may be a better way to approach this

    0 讨论(0)
  • 2021-01-23 08:33

    A number of the answers say to abort the thread. Never abort a thread unless it is an emergency situation and you are shutting down the application.

    The CLR guarantees that its internal data structures are not corrupted by a thread abort. This is the only (*) guarantee made by the CLR with respect to thread aborts. It specifically does not guarantee:

    • That the thread actually will abort. Threads can harden themselves against being terminated.
    • That any data structure that is not in the CLR itself will be uncorrupted. Thread aborts in the middle of crucial operations can leave BCL data structures or user data structures in arbitrarily inconsistent states. This can crash your process mysteriously later.
    • That locks will be released. Aborting threads can cause locks to be held forever, it can cause deadlocks, and so on.

    In case I am not being clear: it is insanely dangerous to abort a thread and you should only do so when all the alternatives are worse.

    So what if you want to start up a thread and then shut it down cleanly?

    First, don't do that. Don't start a thread in the first place. Start a Task<T> with a cancellation token and when you want to shut it down, signal its cancellation token.

    If you do have to start a thread, then start the thread such that there is some mechanism whereby the main thread and the working thread can cleanly and safely communicate "I want you to shut yourself down cleanly at this time".

    If you don't know how to do that then stop writing multithreaded code until you learn how to do that.


    (*) This is a small lie; the CLR also makes certain guarantees with respect to the interactions of thread aborts and special code regions such as constrained execution regions and finally blocks.

    0 讨论(0)
  • 2021-01-23 08:48

    Brutal way (not recommended) - use Thread.Abort method to abort threads. This method raises ThreadAbortException on thread. Like this:

    foreach(Thread thread in thr)
        thread.Abort();
    

    But better way is notifying thread about cancellation and letting it correctly finish its job. You can do it simply with .Net 4 tasks:

    Task[] thr = new Task[threads_count];
    var source = new CancellationTokenSource();
    
    for (int i = 0; i < threads_count; i++)
    {
        thr[i] = Task.Factory.StartNew(go, source.Token);
    }
    
    // later, when condition is met
    source.Cancel();
    

    And here is how cancellation should look like:

    private static void go(object obj)
    {
        CancellationToken token = (CancellationToken)obj;
        while (true)
        {
            if (token.IsCancellationRequested)
                return;
    
            // do some work
        }
    }
    
    0 讨论(0)
提交回复
热议问题