I have some image processing code that runs on a background thread and updates an Image control on the UI thread when it's done processing using Dispatcher.BeginInvoke(). When I'm running my application outside of the debugger, it crashes quite often. As soon as I run it in the debugger, I can't get it to happen at all. Apparently the timing difference is enough to make my life miserable right now ;-)
I've tried putting try/catch blocks around any code that seems relevant and logging any errors that come up, but to no avail - it somehow keeps slipping past me, and I'm not sure where else to look.
My hope for using the debugger was to set the debugger's exception catching behavior to break whenever any exception was thrown, but since I can't get the exception to happen while debugging, I can't find out where my code is throwing.
I can attach to my crashed process (since it stays on screen, just is completely unresponsive), pause the debugger, and see where each thread is in the code, but that doesn't really help me - I have no idea what the actual exception being thrown is.
Any suggestions on how to proceed?
Edit:
- I've been using System.Diagnostics.Trace.WriteLine() with DbgView in as many places as I can think. I can track down where it appears the exception is occurring, I can't find out what the exception is, which is what is important.
- I've used WinDBG+SOS before, to track down memory leaks, but not to track down hard-to-find-exceptions. Can anyone suggest resources for using WinDBG+SOS in this capacity?
-
How can you be sure it's an exception, when you've never caught it?
Also, rather than placing try/catch blocks all over the place, place them at boundaries, especially at thread boundaries. Put them around any ThreadStart methods or other code invoked by BeginInvoke, or callback methods, etc.
unforgiven3 : That is a good question...unforgiven3 : It turned out to be a deadlock in my image processing code. Thanks for the suggestion, I would have spent a lot more time thinking it was an unhandled exception otherwise! -
Can you put one try/catch in the static Main called on application start? So when app crash you can output stacktrace and exception info somewhere.
unforgiven3 : No, it's a multithreaded application. -
With only few exceptions every
BeginInvokeshould have a correspondingEndInvokecounterpart (see here for more details why, one exception is e.g. Control.BeginInvoke).A missing
EndInvokemight be the reason that an exception is not caught by the main thread and your application terminates.Since in your special case you are dealing with
Dispatcher(which does not implementEndInvoke) you will have to handle the Dispatcher.UnhandledException event to catch any exception thrown during execution of a delegate.By the way, a good tool to monitor the
System.Diagnostics.Tracemessages is DbgView from Sysinternals.unforgiven3 : Very familiar with DbgView, and no, every call of BeginInvoke does *not* need a corresponding EndInvoke call. Look at the documentation for Dispatcher - there is no EndInvoke method.0xA3 : Seems you are right for Control.EndInvoke, but in general calling EndInvoke is needed for not leaking any resources and proper exception handling. See the update in my answer.unforgiven3 : Right - I should have specified, I'm using Canvas.Dispatcher. I wasn't aware of Dispatcher.UnhandledException, though, I'll look into that, thanks!
0 comments:
Post a Comment