B
Brian
In a nutshell:
= Application.Run runs the message pump... pulling messages off the Windows
Message Queue and invoking the appropriate handler.
= If during such a message handler an Exception is thrown that is not
handled inside that handler, then it fires the Application.ThreadException
event. By registering a handler for that event, you can deal with such
unhandled Exceptions gracefully, and prevent your application from dieing
unnecessarily.
= We have setup an Application.ThreadException handler... in testing, it
gets invoked and works great.
However, if an Exception is raised during the PRE-PROCESSING of a Windows
Message (in the System code that is responsible for digesting the message on
the queue and deciding what handler to invoke), then that Exception does NOT
fire the Application.ThreadException event. It also does not fire the
AppDomain.UnhandledException event. Such Exceptions abort Application.Run,
disposing of your MainForm. In other words, "poof" your application is
gone!
I assume Microsoft coded it that way assuming they would never have
unhandled Exceptions in that system code... but they do. For example:
at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
at System.Windows.Forms.Control.CreateHandle()
at System.Windows.Forms.ToolStripDropDown.CreateHandle()
at System.Windows.Forms.Control.get_Handle()
at
System.Windows.Forms.ToolStripManager.ModalMenuFilter.PreFilterMessage(Message&
m)
at System.Windows.Forms.Application.ThreadContext.ProcessFilters(MSG&
msg, Boolean& modified)
at
System.Windows.Forms.Application.ThreadContext.PreTranslateMessage(MSG& msg)
at
System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FPreTranslateMessage(MSG&
msg)
at
System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32
dwComponentID, Int32 reason, Int32 pvLoopData)
at
System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32
reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32
reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at TCPSM.Program.Main() in C:\Documents and Settings\briank\My
Documents\Source\Development\Client\Source\TCPSM\Program.cs:line 220
Note that there is nothing but System.Windows.Forms code in that... nowhere
for me to put a catch (other than outside Application.Run, which is too
late). So, my only hope is the handler on Application.ThreadException...
but it never gets called here. (It was successfully called several times
before this point in the app... so, I know I have it hooked up right and it
works.)
Why is CreateHandle getting an Exception? Because I used another app to
fill the 3MB of Desktop Heap memory with windows so that my app would start
getting the "Error creating window handle." exceptions whenever I try to get
a new handle (or otherwise need Desktop Heap space).
Why am I doing that? To emulate when my users (who also use CAD, CAE, and
lots of other heavy duty tools) run out of Desktop Heap space. Our app used
to just crash; with improvements to our exception handling, it now generally
stays up; until the Exception gets raised in message pre-processing, then we
die as before.
Any suggestions? Is there some other event that I gets raised when such
system code gets an Exception? Is there some flag I need to set?
Or do I need to implement my own version of Application.Run such that I can
properly catch Exceptions, unlike Microsoft's code?
(I am assuming that getting Microsoft to fix their buggy .NET 2.0 code is
not too likely.)
= Application.Run runs the message pump... pulling messages off the Windows
Message Queue and invoking the appropriate handler.
= If during such a message handler an Exception is thrown that is not
handled inside that handler, then it fires the Application.ThreadException
event. By registering a handler for that event, you can deal with such
unhandled Exceptions gracefully, and prevent your application from dieing
unnecessarily.
= We have setup an Application.ThreadException handler... in testing, it
gets invoked and works great.
However, if an Exception is raised during the PRE-PROCESSING of a Windows
Message (in the System code that is responsible for digesting the message on
the queue and deciding what handler to invoke), then that Exception does NOT
fire the Application.ThreadException event. It also does not fire the
AppDomain.UnhandledException event. Such Exceptions abort Application.Run,
disposing of your MainForm. In other words, "poof" your application is
gone!
I assume Microsoft coded it that way assuming they would never have
unhandled Exceptions in that system code... but they do. For example:
at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
at System.Windows.Forms.Control.CreateHandle()
at System.Windows.Forms.ToolStripDropDown.CreateHandle()
at System.Windows.Forms.Control.get_Handle()
at
System.Windows.Forms.ToolStripManager.ModalMenuFilter.PreFilterMessage(Message&
m)
at System.Windows.Forms.Application.ThreadContext.ProcessFilters(MSG&
msg, Boolean& modified)
at
System.Windows.Forms.Application.ThreadContext.PreTranslateMessage(MSG& msg)
at
System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FPreTranslateMessage(MSG&
msg)
at
System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32
dwComponentID, Int32 reason, Int32 pvLoopData)
at
System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32
reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32
reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at TCPSM.Program.Main() in C:\Documents and Settings\briank\My
Documents\Source\Development\Client\Source\TCPSM\Program.cs:line 220
Note that there is nothing but System.Windows.Forms code in that... nowhere
for me to put a catch (other than outside Application.Run, which is too
late). So, my only hope is the handler on Application.ThreadException...
but it never gets called here. (It was successfully called several times
before this point in the app... so, I know I have it hooked up right and it
works.)
Why is CreateHandle getting an Exception? Because I used another app to
fill the 3MB of Desktop Heap memory with windows so that my app would start
getting the "Error creating window handle." exceptions whenever I try to get
a new handle (or otherwise need Desktop Heap space).
Why am I doing that? To emulate when my users (who also use CAD, CAE, and
lots of other heavy duty tools) run out of Desktop Heap space. Our app used
to just crash; with improvements to our exception handling, it now generally
stays up; until the Exception gets raised in message pre-processing, then we
die as before.
Any suggestions? Is there some other event that I gets raised when such
system code gets an Exception? Is there some flag I need to set?
Or do I need to implement my own version of Application.Run such that I can
properly catch Exceptions, unlike Microsoft's code?
(I am assuming that getting Microsoft to fix their buggy .NET 2.0 code is
not too likely.)