24

If I need to cancel some operation on a thread, when should I use Thread.Abort vs Thread.Interrupt. I read the documentation on it but not sure which scneario should i use a particular call between two.

If there is any third way of doing it, please let me knwo about it too with pro and cons.

Jeff Yates
  • 61,417
  • 20
  • 137
  • 189
Silverlight Student
  • 3,968
  • 10
  • 37
  • 53

4 Answers4

22

I would avoid using Thread.Abort at all costs. Its behavior is much safer and predictable since .NET 2.0, but there are still some pretty serious pitfalls with it. Most of the aborts inside managed code can be made safe, but not all of them. For example, I believe there are some subtle problems if an abort request is triggered during the processing of a static constructor. Nevermind, the fact that the out-of-band exception can occur at anytime giving you little control over defining where the safe points for shutdown are located.

There are several acceptable ways to terminate a thread gracefully.

  • Use Thread.Interrupt
  • Poll a stopping flag
  • Use WaitHandle events
  • Specialized API calls

I discuss these methods in my answer here.

Community
  • 1
  • 1
Brian Gideon
  • 47,849
  • 13
  • 107
  • 150
  • 2
    "if you abort a thread while it is in unmanaged code" I'm pretty sure Thread.Abort waits until you're back in managed code. Just like a thread that's in a `finally` block won't terminate until it has finished the finally. – CodesInChaos May 10 '11 at 14:22
  • @CodeInChaos: Ah...maybe it is more safe than I realize. I'll look that up. – Brian Gideon May 10 '11 at 14:40
  • @CodeInChaos: Yup, says it right here http://msdn.microsoft.com/en-us/library/74169f59.aspx in the last paragraph. Nice catch! – Brian Gideon May 10 '11 at 14:45
  • @Brian: In the question comments above I added link to give you better picture of the context of where i need aborting this thread . Since this thread is calling a web-service, from your list of acceptable ways, seem like Thread.Interrupt is the only possible solution I can use. Since this thread is just calling an API from web-service and user wants to cancel this operation there is nothing much you can do except shutdown thad thread. Do you agree? – Silverlight Student May 10 '11 at 15:43
  • @Silverlight: In that case you may be able to close the underlying web service channel. Hopefully, that will cause the call to return or throw an exception immediately. This would fall under the 4th option of specialized API calls. – Brian Gideon May 10 '11 at 17:13
  • @Brian: How can that be done? Its an external service hosted by somebody else. All I know is a web-method API that I call. That's it. I don't see what I can do except Abort or Interrupt on that thread. – Silverlight Student May 10 '11 at 17:55
  • "out-of-band exception"? The thread has run out of elastic bands to flick other threads with? – Pharap Mar 30 '14 at 22:18
  • @Pharap: Haha...it's synonymous (or perhaps slang) for asynchronous exception. It's an exception that gets injected into the thread at an unpredictable point. You can see my answer [here](http://stackoverflow.com/a/18155439/158779) for details on how this happens. – Brian Gideon Aug 08 '14 at 15:53
9

Most suggestions are already done, but here's an example how i would do it:

    ManualResetEvent _requestTermination = new ManualResetEvent(false);
    Thread _thread;

    public void Init()
    {
        _thread = new Thread(() =>
         {

             while (!_requestTermination.WaitOne(0))
             {
                 // do something usefull

             }

         }));

        _thread.Start();
    }

    public void Dispose()
    {
        _requestTermination.Set();

        // you could enter a maximum wait time in the Join(...)
        _thread.Join();
    }

This way the dispose will wait until the thread has exited.


If you need a delay within the thread, you shouldn't add Thread.Sleep. Use the WaitOne(delayTime). This way you will never have to wait to terminate it.

Jeroen van Langen
  • 21,446
  • 3
  • 42
  • 57
3

I wouldn't use Thread.Abort ever. It causes an exception at an almost arbitrary time.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
  • Can you elaborate the arbitary time here. It doesn't try to kill the thread right at the point when Abort call is been made? Any links as reference to your statement will help too. – Silverlight Student May 10 '11 at 15:45
  • It will not abort inside a finally clause, inside a try clause it will jump to the finally directly, it can be caught temporarily but will be rethrown at the end of the catch block, and since .net 4 the `lock` statement works as expected. But it can break the `using` statement. Which for me is enough to never use it. – CodesInChaos May 10 '11 at 18:07
2

Be careful with Thread.Interrupt. If you don't build in some waiting or sleeping time the thread won't be interrupted.

Be careful with Thread.Abort. If you catch the ThreadAbortException your thread will terminate right after catch + finally.

(I like to use those methods to send a signal to my thread so that it knows it's terminating time, then clean up and exit.)

Bitterblue
  • 13,162
  • 17
  • 86
  • 124
  • 1
    In the `catch`-block you have to call `Thread.ResetAbort()`. Just for sake of completeness. – Paul Kertscher Jan 16 '17 at 11:25
  • @PaulKertscher No, you don't have to. When you use _Abort_ you **can** use _ResetAbort_ to refuse abortion or continue with extra code _after_ catch + finally (and your loop). – Bitterblue Jan 17 '17 at 11:12