RobinS
Sun Jan 27 20:29:21 CST 2008
"Peter Duniho" <NpOeStPeAdM@nnowslpianmk.com> wrote in message
news:op.t5lqsjzo8jd0ej@petes-computer.local...
> On Sun, 27 Jan 2008 09:43:11 -0800, RobinS <robins@imnottelling.com>
> wrote:
>
>> I agree that you should try to catch any exceptions you can. However,
>> it's a good idea to capture any unhandled exceptions so you can shut
>> down your application, rather than having the Microsoft dialog come up
>> and tell the user the app is no longer working, right?
>
> Well, I disagree. This is a matter of philosophy -- I don't think there
> are objective, unequivocable arguments in either direction -- but I don't
> really see the advantage of one over the other, and my preference is that
> the less code one writes, the less likely one is to write buggy code.
>
> If I write some code, I want it to add some real value to the user.
> Replacing the standard Microsoft "process terminating" dialog with one's
> own doesn't seem to add any real value for the user. In fact, while I
> don't know the details my understanding is that Microsoft has a reporting
> system tied to that dialog that, if you present your own dialog, you
> completely shortcut. I realize most software authors probably don't avail
> themselves of the reporting system, but it's there nonetheless.
>
> It's my feeling that if all you're going to do when you catch an exception
> globally, or receive report of it via some event, is to shut down the
> application then, well...Windows can shut down the application just as
> well as you can.
>
>> So here's my question: What is the difference between handling the
>> AppDomain.CurrentDomain.UnhandledException and handling the
>> ThreadException? Should you handle both of them in your startup class? I
>> thought the ThreadException was to catch exceptions in background
>> threads, but apparently I'm wrong about that?
>
> It would probably be helpful to read the documentation pages for those
> events. I'd start with the high-level discussion of exceptions in managed
> threads:
>
http://msdn2.microsoft.com/en-us/library/ms228965.aspx
>
> And then of course look at the documentation for the specific events.
>
> First, _neither_ event really "catches" exceptions. They are events that
> are raised when unhandled exceptions occur. Generally, UnhandledException
> is for dealing with exceptions in non-GUI threads, while ThreadException
> is raised for exceptions in GUI threads. Subscribing to ThreadException
> does in fact change the behavior of the application if an unhandled
> exception occurs, but it's still not really handling the exception.
>
> Since I don't use either myself (see above regarding my philosophical bent
> with respect to this issue :) ), I can't really offer much precise
> discussion about the events. But my understanding is that with
> ThreadException, you can in fact suppress termination of the application
> due to an exception raised during the processing of a window message if
> you subscribe to the event. With UnhandledException, it not being
> relevant for GUI threads, this doesn't happen. An exception in a non-GUI
> thread will cause the application to terminate regardless.
>
>> And when you do handle them, what do you do? Shut down any database
>> connections and run Application.ExitI() to exit your application? I
>> think you can't put any UI stuff in there, right?
>
> You can theoretically try anything you want. For ThreadException, since
> the message pump hasn't been shut down, any UI stuff should work. For
> UnhandledException, you would need to start up a new message pump (either
> explicitly, or by showing a dialog modally), but you could probably get
> some UI to happen.
>
> But why would you? Shut down database connections? Those will go away
> soon enough once the process has been terminated. How can you be sure you
> can shut them down cleanly? What if the exception occurred while you were
> already trying to shut them down cleanly, and you had a bug in your code
> that prevented that from happening correctly?
>
> The problem with thinking that you can do something to recover from these
> kinds of exceptions is that by definition, they were unexpected and you
> have no reason to believe that _any_ of your data is in a consistent
> state. It could be that none of the data is corrupted, or it could be
> that all of it is. And heaven help you if your code's execution path
> depends on the data (as is very commonly the case), which means that you
> have no idea what code is safe to execute except that which is entirely
> independent of your data (and what use would executing that code be?).
>
> So, the best you can do is perhaps log an error to a file (a file
> dedicated to the purpose of logging unexpected exceptions like this,
> guaranteed to be unrelated to whatever exception occurred). And in fact,
> in some cases this is definitely a useful thing. If you have a close
> relationship with your users and they can be relied upon to provide such a
> file and to discuss with you the nature of the exception, this sort of
> thing can be very useful.
>
> So, it's not that there's no use for this sort of global exception
> handling. It's just that I feel people should be realistic about what
> sorts of things can be done when dealing with exceptions in a global way.
> IMHO, recovery is not a likely option.
>
> Pete
Thanks for all of the information.
Just for your peace of mind, it is not my intention to recover from the
errors. I have logging in place, and I would like to log the exception
information and then exit the application, then I can get a copy of the log
file and see what the exception is. I don't think that is an unrealistic
expectation.
This would be especially helpful in the case of exceptions thrown in the
background threads, since it does not provide the opportunity to do any
logging, it just shuts down the app with no "saveable" indication of what
went wrong.
Thanks again,
RobinS.
GoldMail, Inc.