Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Cancel a Thread?

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 thing with a Thread object?

like image 365
user366312 Avatar asked Dec 08 '09 08:12

user366312


2 Answers

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.

like image 187
Fredrik Mörk Avatar answered Oct 13 '22 21:10

Fredrik Mörk


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;
like image 28
Jamiec Avatar answered Oct 13 '22 20:10

Jamiec