0

I stop a thread execution with .Abort() and .Join() for wait the thread terminates. But the problem is that .Join() never unblock application, same when thread was terminated. Why? my code:

  th.Abort();
  Console.WriteLine("request sent, please wait..");
  th.Join();
  Console.WriteLine("done!");

the above code never unlock application, but it works fine:

th.Abort();
Console.WriteLine("request sent, please wait..");
while (serverTh.ThreadState != ThreadState.Aborted) {
          Thread.Sleep(500);
 }
 Console.WriteLine("done!");

Thanks in advance.

The Mask
  • 17,007
  • 37
  • 111
  • 185
  • 1
    `Thread.Abort` is not a good way to terminate a thread. It makes even less sense followed by a `Join`. – M.Babcock Feb 10 '12 at 01:56
  • 1
    @M.Babcock Both of these statements are wrong. Abort() is the way to signal your .NET thread to terminate and you must handle it accordingly. While .Join() is the appropriate way for your main application to wait for your threads to shut down before exiting itself. – Timeout Feb 10 '12 at 02:00
  • 1
    th != serverTh. So sure, that could work. – Hans Passant Feb 10 '12 at 02:01
  • 1
    `Thread.Abort` should not be your primary means of terminating a thread, but it is quite effective if your thread is in a waiting state. And you should always follow thread termination by a join if you rely on its resources to be released. – Zenexer Feb 10 '12 at 02:01
  • @b1naryj - No, the problem is that the OP is probably using code like that included in Zenexer's answer. `while(true)` is bad form and leads to writing even worse code to terminate the thread to close. – M.Babcock Feb 10 '12 at 02:03
  • @Zenexer - The problem with `Thread.Abort` is it doesn't allow cleanup of resources, including handles. – M.Babcock Feb 10 '12 at 02:04
  • @M.Babcock It does if you catch `ThreadAbortException`. – Zenexer Feb 10 '12 at 02:06
  • @M.Babcock Those two comments are different in meaning. Abort() is perfectly valid for killing a thread as well as Join() for waiting. Neither is an excuse (or cause) for bad code. – Timeout Feb 10 '12 at 02:07
  • I deleted my answer, as the `while (true)` thing catching the `ThreadAbortException` didn't actually prevent the abort. – Zenexer Feb 10 '12 at 02:14
  • 1
    @b1naryj - See [this related question](http://stackoverflow.com/questions/710070/timeout-pattern-how-bad-is-thread-abort-really) regarding why `Thread.Abort` can be devastating. It is just bad practice. `while(true)` on a thread can be potentially as bad if there isn't *some* way provided by the thread to stop the infinite loop gracefully. – M.Babcock Feb 10 '12 at 02:37
  • You should attach a debugger to your application, and see what the aborted thread is blocked on. Is this by any chance a winform application? Is the aborted thread blocked on an invoke call that only the calling thread can service? – Tung Mar 10 '12 at 11:21

1 Answers1

1

What's going on in the thread that you are trying to abort? For instance, this works fine:

    public static void Main(String[] args)
    {
        var t = new Thread(LoopForever);
        t.Start();
        Thread.Sleep(500);
        Console.WriteLine("request sent, please wait..");
        t.Abort();
        t.Join();
        Console.WriteLine("done!");
        Console.ReadLine();
    }

    public static void LoopForever()
    {
        Console.WriteLine("Running!");
        while (true)
        {
            Thread.Sleep(100);
            Console.WriteLine("Running!");
        }
    }

The only thing that comes to mind is maybe your background thread is catching the AbortException and then calling ResetAbort on itself:

    public static void Main(String[] args)
    {
        var t = new Thread(LoopForever);
        t.Start();
        // Let the thread get started...
        Thread.Sleep(500);
        Console.WriteLine("request sent, please wait..");
        t.Abort();
        t.Join();
        Console.WriteLine("done!");
        Console.ReadLine();
    }

    public static void LoopForever()
    {
            Console.WriteLine("Running!");
            while (true)
            {
                try
                {
                    Console.WriteLine("Running!");
                    Thread.Sleep(100);
                }
                catch (ThreadAbortException ex)
                {
                    Console.WriteLine("Alas, I was aborted!");
                    Thread.ResetAbort();
                    Console.WriteLine("But behold, I live!");
                }
            }
    }
Chris Shain
  • 50,833
  • 6
  • 93
  • 125