Home All Groups Group Topic Archive Search About

Thread Abort and Unhandled Exception Event

Author
18 Apr 2007 7:16 AM
pawel.kedzior
Hi

In .NET 2.0 unhandled exceptions in separate threads cause raising
unhandled exception event and terminating the process. This is true
for most exceptions, but not for ThreadAbortException, what is
reasonable.

I have verified this with following example:
   class Program {
        private static void thread() {
            while (true){}
        }
        static void Main(string[] args) {
            AppDomain.CurrentDomain.UnhandledException
                += new UnhandledExceptionEventHandler(handler);
            Thread th = new Thread(new ThreadStart(thread))
            th.Start();
            Thread.Sleep(5000);
            th.Abort();
            Thread.Sleep(50000);
        }

        static void handler(object sender, UnhandledExceptionEventArgs
e) {
            System.Console.WriteLine("Unhandled exception.");
        }
    }

While working with my, quite complex, application, where I must use
Thread.Abort() on one of my threads, I managed to get in the handler
following exception:

Exception: System.Threading.ThreadAbortException
Message: Thread was being aborted.
Source: mscorlib
   at System.Reflection.Assembly.GetType(String name, Boolean
throwOnError, Boolean ignoreCase)
   at System.Activator.CreateInstanceFrom(String assemblyFile, String
typeName, Boolean ignoreCase,
BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo
culture, Object[]
activationAttributes, Evidence securityInfo)
   at System.AppDomain.CreateInstanceFrom(String assemblyFile, String
typeName)

The application terminated immediately because of that.

This convinced me that in some circumstances ThreadAbortException is
treated just as any other exception and can cause process crash
in .NET 2.0.
The above stack trace is a full stack trace which the exception
conveyed, and looks bit strange for me. My code never use
System.AppDomain.CreateInstanceFrom(..) directly, so I guess this is
some internal mechanism of the framwork/CLR.

Can you think what kind of my code can trigger above one ? It looks
like something related to reflection. What is exact reason that the
ThreadAbortException is not treated just as ThreadAbortException in my
example.

Generally this is very bad news for everyone who use Thread.Abort(),
because there are poor guarantees that the operation does not crash
their application.

PS. Do not suggest me using a flag to stop a thread.

Author
18 Apr 2007 8:44 AM
Michael Nemtsev
Hello pawel.kedz***@gmail.com,


> In .NET 2.0 unhandled exceptions in separate threads cause raising
> unhandled exception event and terminating the process. This is true
> for most exceptions, but not for ThreadAbortException, what is
> reasonable.

The ThreadAbortException is asyn exception and can interrupt the target thread
at any point

> While working with my, quite complex, application, where I must use
> Thread.Abort() on one of my threads, I managed to get in the handler
> following exception:

It's the well known that Thread.Abort is evil and your need to use other
ways to interrupt your thread gracefully

> This convinced me that in some circumstances ThreadAbortException is
> treated just as any other exception and can cause process crash
> in .NET 2.0.

Yep, as async exceptions

> Can you think what kind of my code can trigger above one ? It looks
> like something related to reflection. What is exact reason that the
> ThreadAbortException is not treated just as ThreadAbortException in my
> example.

Because it can be arrised at any point, and not where you expect it

> Generally this is very bad news for everyone who use Thread.Abort(),
> because there are poor guarantees that the operation does not crash
> their application.

Yep, it is.

> PS. Do not suggest me using a flag to stop a thread.

I recommend you to read this http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation
and this  http://www.dotnetconsult.co.uk/weblog/PermaLink.aspx/4f52c396-1b0d-4419-8871-6ca6992460ca






---
WBR,  Michael  Nemtsev [.NET/C# MVP]. 
My blog: http://spaces.live.com/laflour
Team blog: http://devkids.blogspot.com/

"The greatest danger for most of us is not that our aim is too high and we
miss it, but that it is too low and we reach it" (c) Michelangelo
Author
18 Apr 2007 12:08 PM
pawel.kedzior
Hi Michael

Thank you for your response, but this still does not explain a few
things.

I agree that async exception can emerge in any location, I can not
predict location in my code where does it happen, but
I should be able to assume that stack trace of the exception will have
at its bottom initial frame of my thread.
The stack trace which I handled doesn't have such, it has only
some .net framwork methods, see my first post.

Also, I still claim that ThreadAbortException should not cause
application crash directly by it self
(by the fact that it was not caught - and moreover was not suppressed
by Thread.ResetAbort()).

Of course it may crash the application indirectly, because of changed
flow, but anyway not ThreadAbortException should by received by
unhandled exceptions event.

zuraff
Author
18 Apr 2007 12:31 PM
Göran_Andersson
pawel.kedz***@gmail.com wrote:
Show quote
> Hi
>
> In .NET 2.0 unhandled exceptions in separate threads cause raising
> unhandled exception event and terminating the process. This is true
> for most exceptions, but not for ThreadAbortException, what is
> reasonable.
>
> I have verified this with following example:
>    class Program {
>         private static void thread() {
>             while (true){}
>         }
>         static void Main(string[] args) {
>             AppDomain.CurrentDomain.UnhandledException
>                 += new UnhandledExceptionEventHandler(handler);
>             Thread th = new Thread(new ThreadStart(thread))
>             th.Start();
>             Thread.Sleep(5000);
>             th.Abort();
>             Thread.Sleep(50000);
>         }
>
>         static void handler(object sender, UnhandledExceptionEventArgs
> e) {
>             System.Console.WriteLine("Unhandled exception.");
>         }
>     }
>
> While working with my, quite complex, application, where I must use
> Thread.Abort() on one of my threads, I managed to get in the handler
> following exception:
>
> Exception: System.Threading.ThreadAbortException
> Message: Thread was being aborted.
> Source: mscorlib
>    at System.Reflection.Assembly.GetType(String name, Boolean
> throwOnError, Boolean ignoreCase)
>    at System.Activator.CreateInstanceFrom(String assemblyFile, String
> typeName, Boolean ignoreCase,
> BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo
> culture, Object[]
> activationAttributes, Evidence securityInfo)
>    at System.AppDomain.CreateInstanceFrom(String assemblyFile, String
> typeName)
>
> The application terminated immediately because of that.
>
> This convinced me that in some circumstances ThreadAbortException is
> treated just as any other exception and can cause process crash
> in .NET 2.0.
> The above stack trace is a full stack trace which the exception
> conveyed, and looks bit strange for me. My code never use
> System.AppDomain.CreateInstanceFrom(..) directly, so I guess this is
> some internal mechanism of the framwork/CLR.
>
> Can you think what kind of my code can trigger above one ? It looks
> like something related to reflection. What is exact reason that the
> ThreadAbortException is not treated just as ThreadAbortException in my
> example.
>
> Generally this is very bad news for everyone who use Thread.Abort(),
> because there are poor guarantees that the operation does not crash
> their application.
>
> PS. Do not suggest me using a flag to stop a thread.
>

The ThreadAbortException is used to abort the thread while giving the
thread an opportunity to clean up critical data.

The thread should catch the ThreadAbortException, do any neccesary
cleanup, and return from the method.

If possible, Thread.Abort should be avoided. As it stops the thread
whatever if might be doing, it might be difficult to write the cleanup
code so that it can properly handle every possible state that the code
can be in.

--
Göran Andersson
_____
http://www.guffa.com
Author
18 Apr 2007 6:29 PM
pawel.kedzior
Thanks Goran

What you says is clear to me.

However I'm looking for the answer for following question: When
ThreadAbortException, when it reaches bottom of stack trace of its
thread causes AppDomain.UnhandledException event and terminating the
application ?

I don't mind illegal state of my code, because of change of the flow
due to Thread.Abort().
Author
18 Apr 2007 6:51 PM
Peter Duniho
On Wed, 18 Apr 2007 11:29:19 -0700, <pawel.kedz***@gmail.com> wrote:

> However I'm looking for the answer for following question: When
> ThreadAbortException, when it reaches bottom of stack trace of its
> thread causes AppDomain.UnhandledException event and terminating the
> application ?

I think you misunderstand the nature of "UnhandledException".  It's an 
event, not an exception handler.

This has two important implications:

     1) It's not running in the thread where the exception occured.  That 
is, it doesn't "reach the bottom of stack trace of its thread".  The 
thread has no handler for the exception, and so the thread crashes.

     2) It's not *handling* the exception.  It's simply giving you notice 
that an unhandled exception occurred.  This may or may not be a problem 
for you, but the fact remains that the exception wasn't ever handled and 
if not handling the exception results in instability your entire process 
may indeed crash.

If you insist on using Thread.Abort(), then you need to put an exception 
handler in the thread itself (that is, try/catch at the top of the thread 
*and* make sure that you never abort the thread unless you are 100% 
certain that the thread is within the try block).  Really, you should not 
be using Thread.Abort() at all.  But if you insist on doing so, then you 
need to handle the exception if you expect for the exception to be handled 
properly.

Pete
Author
18 Apr 2007 7:55 PM
pawel.kedzior
Hi Pete
> I think you misunderstand the nature of "UnhandledException".  It's an
> event, not an exception handler.
I might have called that a handler, but I never thought so. The key is
that once the application is terminating, you can not cancel the
process.

> then you need to put an exception
> handler in the thread itself (that is, try/catch at the top of the thread
> *and* make sure that you never abort the thread unless you are 100%
> certain that the thread is within the try block).

So what you suggest is to:

Thread th = new Thread(new ThreadStart(foo)); th.Start();
....
th.Abort();
....

public void foo() {
   try {
      ...
    } catch (Exception e)
    {...}
}

I understand that you claim that the catch block will prevent from
slipping ThreadAbortException outside foo() if only Abort was called
within try/catch.

That is not actually true, because ThreadAbortException will be
rethrown automatically after leaving catch{} block, provided that
Thread.ResetAbort() was not called before.

But usually, e.g. in my example in the first post, it is okey. CLR
just suppresses that type of exceptions once they slip out of the
thread and process is not terminated. Nothing bad happens.

But for some reason, which I need to discover, some time CLR does not
suppress it and the process IS terminated. Moreover the stack trace
which I managed to log in that case (see my first post) using
UnhandledException event, does not consist my code, and doesn't give
me any chance to add try/catch(){ Thread.ResetAbort();} which will
prevent from slipping it outside.
Author
18 Apr 2007 10:50 PM
Peter Duniho
On Wed, 18 Apr 2007 12:55:46 -0700, <pawel.kedz***@gmail.com> wrote:

> [...]
> I understand that you claim that the catch block will prevent from
> slipping ThreadAbortException outside foo() if only Abort was called
> within try/catch.

That's correct.

> That is not actually true, because ThreadAbortException will be
> rethrown automatically after leaving catch{} block, provided that
> Thread.ResetAbort() was not called before.

This statement has very little to do with the previous.  I never suggested 
that including an exception handler would prevent the thread from being 
aborted.  I am only pointing out that if you want to catch the exception, 
you have to have some code that it set up to catch exceptions.

> [...]
> But for some reason, which I need to discover, some time CLR does not
> suppress it and the process IS terminated.

You can try to figure that issue out if you like.  However, the 
fundamental nature of what you're doing is so wrong in the first place, 
it's my opinion that what you really ought to be doing is fixing your 
design so that you don't rely on the behavior of Thread.Abort() in the 
first place.

> Moreover the stack trace
> which I managed to log in that case (see my first post) using
> UnhandledException event, does not consist my code, and doesn't give
> me any chance to add try/catch(){ Thread.ResetAbort();} which will
> prevent from slipping it outside.

That suggests to me that by aborting your thread, you are somehow screwing 
up some other thread.  How that might happen, I don't know, and I can't 
rule out the possibility of a .NET bug.  Still, since you're not 
exercising good thread-management behavior in the first place, it's hard 
to work up much interest in figuring out your problem for you.

I realize you started out telling us all (in effect) to not tell you to 
not use Thread.Abort().  But really, that's the best advice anyone could 
give you.

Pete

AddThis Social Bookmark Button