How to Cancel a Thread?

前端 未结 4 1943
旧巷少年郎
旧巷少年郎 2020-12-06 13:18

In case of BackgroundWorker, a cancel can be reported by the e.Cancel - property of the DoWork - event handler.

How can I achieve the same

相关标签:
4条回答
  • 2020-12-06 13:58

    Here is a full example of one way of doing it.

    private static bool _runThread;
    private static object _runThreadLock = new object();
    
    private static void Main(string[] args)
    {
        _runThread = true;
        Thread t = new Thread(() =>
        {
            Console.WriteLine("Starting thread...");
            bool _localRunThread = true;
            while (_localRunThread)
            {
                Console.WriteLine("Working...");
                Thread.Sleep(1000);
                lock (_runThreadLock)
                {
                    _localRunThread = _runThread;
                }
            }
            Console.WriteLine("Exiting thread...");
        });
        t.Start();
    
        // wait for any key press, and then exit the app
        Console.ReadKey();
    
        // tell the thread to stop
        lock (_runThreadLock)
        {
            _runThread = false;
        }
    
        // wait for the thread to finish
        t.Join();
    
        Console.WriteLine("All done.");    
    }
    

    In short; the thread checks a bool flag, and keeps runing as long as the flag is true. I prefer this approach over calling Thread.Abort becuase it seems a bit nicer and cleaner.

    0 讨论(0)
  • 2020-12-06 13:58

    A blocked thread can be stopped prematurely in one of two ways:

    • Thread.Interrupt

    • Thread.Abort

    The main question is if the thread works on any ressources which need to be released correctly - in this case - you need to work with a property on the actual object which runs the thread.

    0 讨论(0)
  • 2020-12-06 14:02

    There's Thread.Abort, which works by injecting a ThreadAbortException into the thread. It's a little risky because:

    1. Your thread can get stuck if it's executing native code at the time
    2. The code in the thread better be exception-safe, because this ThreadAbortException could happen on any line of code within it, even something innocent like i = i + 1

    You're better off coding your own signalling mechanism between your GUI thread and the background thread. It's hard to recommend something without knowing what's going on inside that thread, but where I have a thread that works by waiting on some object in a loop, I use an AutoResetEvent and wait on that too.

    0 讨论(0)
  • 2020-12-06 14:19

    Generally you do it by the thread's execute being a delegate to a method on an object, with that object exposing a Cancel property, and the long-running operation periodically chercking that property for tru to determine whether to exit.

    for example

    public class MyLongTunningTask
    {
       public MyLongRunninTask() {}
       public volatile bool Cancel {get; set; }
    
       public void ExecuteLongRunningTask()
       {
         while(!this.Cancel)
         {
             // Do something long running.
            // you may still like to check Cancel periodically and exit gracefully if its true
         }
       }
    }
    

    Then elsewhere:

    var longRunning = new MyLongTunningTask();
    Thread myThread = new Thread(new ThreadStart(longRunning.ExecuteLongRunningTask));
    
    myThread.Start();
    
    // somewhere else
    longRunning.Cancel = true;
    
    0 讨论(0)
提交回复
热议问题