52

I am using the thread.Abort method to kill the thread, but it not working. Is there any other way of terminating the thread?

private void button1_Click(object sender, EventArgs e)
{
    if (Receiver.IsAlive == true)
    {
        MessageBox.Show("Alive");
        Receiver.Abort();
    }
    else
    {
        MessageBox.Show("Dead");
        Receiver.Start();
    }
}

I am using this but every time I get the Alive status, Receiver is my global thread.

Right leg
  • 16,080
  • 7
  • 48
  • 81
Mobin
  • 4,870
  • 15
  • 45
  • 51
  • 13
    Danger, Will Robinson, Danger! Be **very** shy of using Thread.Abort - almost always a bad idea. – Marc Gravell Aug 25 '09 at 09:29
  • 4
    Then what should be used to kill the thread? – Mobin Aug 25 '09 at 09:30
  • 3
    Ask the thread to stop, and ignore the thread from that moment on. – MSalters Aug 25 '09 at 09:47
  • 17
    If you absolutely, positively have to take it down a thread running arbitrary, potentially hostile-to-being-taken-down code, then the only reasonably safe and effective way to do it is to isolate that thread into its own process. There is no guarantee that a thread abort will ever succeed, but you should be able to take down a process. – Eric Lippert Aug 25 '09 at 17:08
  • 1
    To add to the comments of this (old) question, here is a related (old) question: "[*What's wrong with using Thread.Abort()*](http://stackoverflow.com/q/1559255/1364007)". – Wai Ha Lee Apr 10 '15 at 11:12
  • to put it simple Abort doesn't work – Toolkit Jan 13 '21 at 16:14

5 Answers5

77

The reason it's hard to just kill a thread is because the language designers want to avoid the following problem: your thread takes a lock, and then you kill it before it can release it. Now anyone who needs that lock will get stuck.

What you have to do is use some global variable to tell the thread to stop. You have to manually, in your thread code, check that global variable and return if you see it indicates you should stop.

redtuna
  • 4,586
  • 21
  • 35
  • I use this mechanism myself. For UI-based code, I set a global variable, and for services I check a database table. Nice and predictable. – Ed Power Aug 27 '09 at 19:33
  • 6
    If possible, use a ManualResetEvent instead of a variable, its what they are designed for. – Steve Sheldon Jul 13 '11 at 20:02
  • 3
    I'm curious now - how would the ManualResetEvent be superior, for checking an early termination condition? I understand they're better when we have to block on something, but there is no blocking here. – redtuna Jun 25 '12 at 21:14
  • Basically I agree, but in very specific situations (you have a thread that does not need to be synchronized to other ones - then you can check my solution below). – Nickon Mar 10 '15 at 12:59
  • I prefer [Adrian Regan's answer](http://stackoverflow.com/a/1327377/199364), which includes code for telling a thread it should be stopping (`interrupt`), and then if the thread fails to stop within the agreed-upon amount of time, finally resorts to `abort`. – ToolmakerSteve Oct 09 '16 at 14:20
34

You can kill instantly doing it in that way:

private Thread _myThread = new Thread(SomeThreadMethod);

private void SomeThreadMethod()
{
   // do whatever you want
}

[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
private void KillTheThread()
{
   _myThread.Abort();
}

I always use it and works for me:)

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
Nickon
  • 9,652
  • 12
  • 64
  • 119
24

You should first have some agreed method of ending the thread. For example a running_ valiable that the thread can check and comply with.

Your main thread code should be wrapped in an exception block that catches both ThreadInterruptException and ThreadAbortException that will cleanly tidy up the thread on exit.

In the case of ThreadInterruptException you can check the running_ variable to see if you should continue. In the case of the ThreadAbortException you should tidy up immediately and exit the thread procedure.

The code that tries to stop the thread should do the following:

running_ = false;
threadInstance_.Interrupt();
if(!threadInstance_.Join(2000)) { // or an agreed resonable time
   threadInstance_.Abort();
}
MBH
  • 16,271
  • 19
  • 99
  • 149
Adrian Regan
  • 2,240
  • 13
  • 11
  • 4
    This is the only acceptable answer from my perspective. Yes, you first need a variable to note when the thread may exit but if you are blocking inside the thread you may never get the opportunity to check that variable. There needs to be another way to interrupt a thread that is blocked and this answer solved my problem. Thanks! – CramerTV Apr 10 '13 at 18:03
  • If `threadInstance_.Interrupt()` ends the thread fast, `threadInstance_.Join` will throw *System.Threading.ThreadStateException: Thread has not been started* – djk Aug 16 '17 at 00:45
  • I wonder can I use Interrupt with something like puppeteer-sharp that doesn't implement CancellationToken? – Toolkit Jan 13 '21 at 16:00
  • this doesn't work actually, the `threadInstance_` keeps working – Toolkit Jan 13 '21 at 16:07
9

Thread will be killed when it finishes its work, so if you are using loops or something, you should pass variable to the thread to stop the loop. After that, the thread will be finished.

Pang
  • 9,564
  • 146
  • 81
  • 122
Wael Dalloul
  • 22,172
  • 11
  • 48
  • 57
6

C# Thread.Abort is NOT guaranteed to abort the thread instantaneously. It will probably work when a thread calls Abort on itself but not when a thread calls on another.

Please refer to the documentation: http://msdn.microsoft.com/en-us/library/ty8d3wta.aspx

I have faced this problem writing tools that interact with hardware - you want immediate stop but it is not guaranteed. I typically use some flags or other such logic to prevent execution of parts of code running on a thread (and which I do not want to be executed on abort - tricky).

Sesh
  • 5,993
  • 4
  • 30
  • 39