Mark
Mark

Reputation: 5523

How to handle AppDomain.Unload and the related ThreadAbortException

According to MSDN, AppDomain.Unload causes all threads inside the unloading AppDomain to throw a thread abort exception.

The threads in domain are terminated using the Abort method, which throws a ThreadAbortException in the thread. Although the thread should terminate promptly, it can continue executing for an unpredictable amount of time in a finally clause. -- from MSDN

So my understanding then is that everytime i'm writing code anywhere that is expected to run in this AppDomain, I have to expect that a thread abort could happen on any thread at any time. Is this true? Should all code everywhere assume that a ThreadAbortException can be thrown at any time?

Practically this virtually elimates catch(Exception ex) because that would catch the ThreadAbortException and try to handle it, usually by logging an error that really shouldn't be logged (since unloading of AppDomain isn't really an exception).

Are there any other considerations that need to be taken to avoid unecessary exception handling / error logging?

Upvotes: 2

Views: 2400

Answers (2)

Chris Shain
Chris Shain

Reputation: 51344

You pretty much have the expectation correct regarding the possibility of TAEs at any time. The only point I'd make is that your code should probably already be written this way- when handling data that has reliability requirements, you should be using transactions or other compensation mechanisms in cases of hardware failure, operator error, OOMs, etc - any of which are not unique to the scenario of AppDomain shutdown.

Finally, you should know that you can catch TAEs and execute compensatory code in the catch block. The only thing special about them is that they will be immediately rethrown after the catch block, so you can't "swallow" them. You can suppress them by using Thread.ResetAbort(), but in this case that probably isn't the desired effect.

We've all written code like this:

public void Foo() {
    try {
        Do.Some.Stuff();
    } catch (Exception ex) {
       Console.Out.WriteLine("Oh noes!");
    }
}

And yes, the catch block will catch everything1, including TAEs and OOMs.

The thing to keep in mind here is that for all of the above exceptions, the world is basically ending. All you should care about is that whatever transactionally sensitive data that you are dealing with doesn't get lost or left in a bad state, and that's why we generally leave things like transactionally-safe I/O to the smart folks at Microsoft and Oracle who write databases. If your code is doing, for instance, flat file I/O that you need to be really sure never leaves the file in a bad state, then you should be thinking about failure modes in a very holistic way- like "what happens if the power goes out when this file is half-written?"

1 The sole exception is that StackOverflow exceptions generally cannot be caught. This was a change in .NET 2.0.

Upvotes: 5

Aliostad
Aliostad

Reputation: 81700

You cannot handle ThreadAbortException so no need to catch the exception. More technically

is a special exception that can be caught, but it will automatically be raised again at the end of the catch block

From here.

Upvotes: 1

Related Questions