none
Strange behaviour of Thread.Abort() RRS feed

  • Question

  • if uncomment
    Console.Write
    thread may be abort , otherwise can not be abort.

    using System;
    using System.Threading;
    
    namespace ThreadAbortStrange
    {
        class Program
        {
            private static object o = new object();
    
            private static int create ;
            private static int abort ;
    
    
            public static void Run2()
            {
                lock (o)
                {
                    try
                    {
                        int i = 0;
    
                        while (true)
                        {
                            //Console.Write(""); // if it uncomment , thread may be abort ,  otherwise can not be abort
                            try
                            {
    
                            }
                            finally
                            {
                                for (int j = 0; j < 100000; j++)
                                {
                                   
                                }
    
                                create++;
                            }
                            i++;
                        }
    
                    }
                    catch (ThreadAbortException)
                    {
                        abort++;
                        Console.Write("A"+ abort );
                    }
    
    
                }
            }
    
            static Random rnd = new Random();
    
            static void Main(string[] args)
            {
                while (true)
                {
                    Console.WriteLine("C" + create );
    
                    Thread t = new Thread(Run2);
                    t.Start();
                    Thread.Sleep(rnd.Next(10));
    
                    t.Abort();
                    t.Join();
    
                }
            }
        }
    }


    Friday, August 28, 2009 8:15 PM

Answers

  • Thread.Abort is not a good idea to use.

    It doesn't guarantee that a thread will be aborted.  Even the documenation just says "Calling this method usually terminates the thread."

    There are cases, such as what you've found, where this may not work.

    I recommend reworking this to use a different mechanism for determining how and when to exit your loop.  Aborting a thread is a bad practice, and I would avoid it.
    Reed Copsey, Jr. - http://reedcopsey.com
    • Marked as answer by eryang Friday, September 4, 2009 3:39 AM
    Friday, August 28, 2009 8:26 PM
    Moderator
  • Your thread does spend rather a long time inside a finally block.  They are special, code inside them can't be aborted.  Things get interesting when you change the for() loop end condition.  If you make it 10, you unwedge it, albeit slowly.  On my machine, 60 still kinda works but is getting very intermittent.  100 pretty much puts an end to it, although I'm sure it would manage to abort it eventually.

    This provides some insight in how the CLR implements the ThreadAbortException.  Clearly it periodically tries to inject it but the thread must be in the right state.  The less chance you give it, the longer it will take for the abort to take effect.  With Console.WriteLine() in the loop, there's lots of opportunity.

    The fix seems simple enough: make your finally blocks short and sweet.

    Hans Passant.
    • Marked as answer by eryang Friday, September 4, 2009 3:39 AM
    Friday, August 28, 2009 9:01 PM
    Moderator

All replies

  • Thread.Abort is not a good idea to use.

    It doesn't guarantee that a thread will be aborted.  Even the documenation just says "Calling this method usually terminates the thread."

    There are cases, such as what you've found, where this may not work.

    I recommend reworking this to use a different mechanism for determining how and when to exit your loop.  Aborting a thread is a bad practice, and I would avoid it.
    Reed Copsey, Jr. - http://reedcopsey.com
    • Marked as answer by eryang Friday, September 4, 2009 3:39 AM
    Friday, August 28, 2009 8:26 PM
    Moderator
  • "Calling this method usually terminates the thread."

    cool! )
    Friday, August 28, 2009 8:49 PM
  • Your thread does spend rather a long time inside a finally block.  They are special, code inside them can't be aborted.  Things get interesting when you change the for() loop end condition.  If you make it 10, you unwedge it, albeit slowly.  On my machine, 60 still kinda works but is getting very intermittent.  100 pretty much puts an end to it, although I'm sure it would manage to abort it eventually.

    This provides some insight in how the CLR implements the ThreadAbortException.  Clearly it periodically tries to inject it but the thread must be in the right state.  The less chance you give it, the longer it will take for the abort to take effect.  With Console.WriteLine() in the loop, there's lots of opportunity.

    The fix seems simple enough: make your finally blocks short and sweet.

    Hans Passant.
    • Marked as answer by eryang Friday, September 4, 2009 3:39 AM
    Friday, August 28, 2009 9:01 PM
    Moderator
  • i think 
    how thread try abort yourself must be write in msdn

    if it fundumental behaviour , of course.
    Friday, August 28, 2009 10:41 PM
  • The MSDN Library article for Thread.Abort() explicitly talks about the effect of finally blocks.  You can annotate the article if you wish, bottom of the page, section marked "Community content".
    Hans Passant.
    Friday, August 28, 2009 11:15 PM
    Moderator