Freigeben über


Answer: More Exception Mysteries

Well, you folks were a lot quicker than I was… Steve got basically what I was looking for very quickly after I posted... Ben’s answer (to add his own local Exception class) was cute, but was clearly cheating as I did say no new classes…

What I was looking for exactly was:

class Program

{

    static void Main(string[] args)

    {

        AppDomain.CurrentDomain.ExceptionThrown += delegate

        {

            Console.WriteLine("Mystery inserted code");

        };

        try

        {

            Console.WriteLine("In try");

            throw new Exception();

        }

        catch (Exception)

        {

            Console.WriteLine("In catch");

        }

        Console.WriteLine("After try..catch");

    }

}

Notice I used the ExceptionThrown event while Steve and co used the CatchingException event… Both happen to work in this case. Peter and I talked about the difference between these two events… it seems that CatchingException occurs when a catch block is found for a managed exception that has been thrown, before the catch block is entered. While ExceptionThrown occurs when a managed exception is thrown, or when an unmanaged exception reaches managed code for the first time.

If you hook both of them, you see the sequence they event handlers fire in:

In try

ExceptionThrownHandler

CatchingExceptionHandler

In catch

After try..catch

Have fun!

Comments

  • Anonymous
    October 24, 2004
    This sequence of events implies that the events are delivered on the same thread on which the exception has been thrown and caught. Is this actually the case, or is this just an artifact of this particular test?

    If the events are delivered on the same thread then this has implications about thread-relative state, such as the thread stack, security invariants, culture, etc. I'd just like to confirm if this is the case. I'm also curious about considerations of appdomain boundaries when subscribing to the new events.

    Also, what would the sequence have been if there was a finally block in a called method? I'd test this myself but I don't have Whidbey installed. I'm curious about the timing of the events and actions. Thanks.

    public void Main()
    {
    AppDomain.CurrentDomain.ExceptionThrown += delegate { Console.WriteLine("ExceptionThrownHandler"); }
    AppDomain.CurrentDomain.CatchingException += delegate { Console.WriteLine("CatchingExceptionHandler found"); }
    try
    {
    Console.WriteLine("In try");
    Method1();
    }
    catch (Exception)
    {
    Console.WriteLine("In catch");
    }
    Console.WriteLine("After try..catch");
    }

    public void Method1()
    {
    try
    {
    Console.WriteLine("In Method1 try");
    throw new Exception();
    }
    finally
    {
    Console.WriteLine("In Method1 finally");
    }
    }

    I would expect the sequence to be:
    In Try
    In Method1 try
    ExceptionThrownHandler
    CatchingExceptionHandler found
    In Method1 finally
    In Catch
    After try..catch

  • Anonymous
    October 24, 2004
    The comment has been removed
  • Anonymous
    October 24, 2004
    Hmm. The first use that occurs to me is exception logging. But that raises the question... what happens if the ExceptionThrownHandler ends up throwing another exception? Does the event get fired again, or does the runtime deliberately not fire it again (to avoid infinite loops)?
  • Anonymous
    October 25, 2004
    Jeff.

    http://www.codeproject.com/dotnet/unhandledexceptions.asp may be helpful.
  • Anonymous
    May 24, 2006
    A vectored exception handler (see kernel32!AddVectoredExceptionHandler) lets you add to a global list...