I'm looking for some guidance on best practices on handling exceptions in events. Currently, when exceptions are thrown in my application, the exception message is displayed in a pop up dialog and then the application restarts after hitting ok. The issue I'm seeing is that a lot of exceptions are occurring in the event handlers of some third party libraries and these exceptions are swallowed and never displayed since they are on a background thread. Here are a few solutions that various people have thought of and I would like to know of any of these are the best approach.
Forward the background thread to the UI thread in every event handler in the application.
Wrap the events in another class which has a try/catch around every method that invokes the event. The catch will then forward the exception to the UI thread if one occurs.
Get access to the third party libraries and put try/catch around where the events are being invoked, which could then be forwarded to the main application by a global event.
Lets discuss your options the way you listed them:
1) Forward the background thread to the UI thread in every event
handler in the application.
You should not and you can't! because:
You can't pretend if that event "which may comes from a third party" starts another background thread
or timer.
The whole point of having background threads is not
to freeze the UI, you will then struggle the user interface by a long execution codes.
2) Wrap the events in another class which has a try/catch around every method that invokes the event. The catch will then forward the exception to the UI thread if one occurs.
The same point as the previous. you can't pretend it that event starts another thread..
3) Get access to the third party libraries and put try/catch around where the events are being invoked, which could then be forwarded to the main application by a global event.
This is a bad choice, really, You should not change that code of third party libraries even if you can. because:
You are not the author for those libraries.
Whenever you want to update the library version or even change the libraries, you have to rewrite there code..
So what you have to do? The answer is some sort of what you are currently doing:
Whenever any exception thrown, log the exception restart your process, and at some point in your process send the logged bugs to your email and then start fixing them.
None of the above. Instead hook up the events on the Application and AppDomain for unhandled exceptions.
AppDomain.CurrentDomain.UnhandledException Event
Application.DispatcherUnhandledException Event
Further Information: The global exception handling event for WPF applications Application.DispatcherUnhandledException fires only for exceptions thrown on the main UI thread. However the AppDomain.CurrentDomain.UnhandledException should fire on any unhandled exception in any thread (unfortunately there is no preventing the application from shutting down after ward it reaches here).
Did some quick research on best practices and found that it is recommend that you manually handle exceptions on the background threads with try\catch block. Read the exception part on this page http://www.albahari.com/threading/ and also take a look at this StackOverflow question Catching unhandled exception on separate threads
If you're hooking the AppDomain.UnhandledException event, then the issue isn't the fact that they might be calling back on a background thread, but rather than the third-party library is explicitly swallowing exceptions thrown by the handlers. This is a badly behaving library, but, since you're writing the event handler code, you can catch the exceptions in the event handler and force the application to shut down.
Since the third-party library can't be stopped by throwing an exception, you can force the thread to terminate by calling:
Thread.CurrentThread.Abort();
Thread.Abort() is generally considered a bad practice, but it's slightly less dangerous here, as you are aborting yourself and therefore won't be injecting the exception into potentially nasty locations (you also know that the thread is not in an unmanaged context, so it will abort right away.) It's still a nasty hack, but the third-party application isn't giving you much choice. ThreadAbortException cannot be 'stopped', so the third-party code will terminate its thread as soon as it reaches the end of its exception handlers (even if they try to swallow it). If the third-party library is really nasty, it might invoke lots of code in its catch or finally blocks, even using dirty tricks to stay alive like launching other threads, but it would have to be pretty malicious to do this.
To get the friendly error message behavior, you can marshal the Exception to your UI thread using a SynchronizationContext or Dispatcher to call your exception-handler display (the easiest way may be to just re-throw the exception; I recommend embedding it as an InnerException so that you don't lose stack trace.)
If you really distrust the library (and don't want to give it the opportunity to stay alive even through its catch and finally blocks), you can explicitly marshal to the UI thread with a blocking invoke (to display your error message in a friendly way) and then call Environment.FailFast() to kill your process. This is a particularly harsh way to terminate (it will not call any cleanup code and literally tears down the process as quickly as possible), but it minimizes the possibility for any potentially damaging side effects if application state has become very corrupted. One possible thing to watch for here is that the UI thread could be blocked by some other UI invocation tied to the third-party code. If this happens, the application will deadlock. Again, this would be a pretty malicious thing for it to do, so you can probably ignore it.
Related
I'm working in a legacy project that has this exception handling code in many methods.
catch(ThreadAbortException e)
{
...
}
I don't see anywhere in the project Thread.Abort() or Thread.Interrupt() calls. Is it safe to delete all these ThreadAbortException handling or it is some other way that can be raised.
Well if answering specifically your question I would say that it would be better not to delete these exception handlers as it’s most likely that they were added by some developer trying to solve a problem. And I think there was a reason to add those handlers so if you just remove this code it can lead to appearing of some bugs again in the future.
Regarding the ThreadAbordException: I know for sure that it can be throwed not only with calling Thread.Abort() method when you are debugging (it might be a bug in VS, I’m not sure) and it forces your program to just crash silently. So depending on what’s inside of those handlers it could be possible that a developer was trying to solve such problem.
Also remember that you could be invoking methods of third-party libraries, web-services etc. in a separate thread, too. I’m not sure if they can throw such an exception but that’s a possible case to consider.
Official docs: "The exception that is thrown when a call is made to the Abort method." If you are completely sure there are no calls to Thread.Abort then you might as well erase those catch blocks.
EDIT: Be mindful that your code may be running in the context of an external app that may call Thread.Abort on your threads.
Not that it matters anyway as a ThreadAbortException can't really be handled as the CLR itself will rethrow it to actually kill the thread ASAP.
"Actually yes, a ThreadAbortException is special. Even if you handle it, it will be automatically re-thrown by the CLR at the end of the try/catch/finally. (As noted in the comments, it can be suppressed with ResetAbort but by that point the code smells like rotten fish.)"
- Read this question for more details: ThreadAbortException
Is the project running on a main thread and spinning up background worker threads? If the main thread exits while background threads are running, a ThreadAbortedException can occur on the background threads.
The catch statement could specifically handle this scenario, where no error actually occurred on the background thread, in a different manner than any other exception.
I want to log uncaught exceptions in a C# windows store project.
For code executing in the UI thread I can use the Windows.UI.Xaml.Application.Current.UnhandledException event, but exceptions from code executing in the tread pool do not trigger that event.
I could try to ensure all of the 'RunAsync' calls are wrapped to log uncaught exceptions, but it's very easy to accidentally bypass that solution. Is there something for this that's already in the API?
I'm not sure if there is something available, but you could create your own version of RunAsync, that takes an action to execute and wraps it in a try/catch block before executing it using the platform version of the RunAsync and just keep making sure this is the only method you use to run things in the background.
Other than that - debugging with breaks on all exceptions enabled (Alt+Ctrl+E, check all) should help you find the problem areas.
How do you schedule code to run as a Threadpoolthread? In case you are using Tasks, check the UnobservedException Event on the TaskScheduler
System.Threading.Tasks.TaskScheduler.UnobservedTaskException +=new EventHandler<UnobservedTaskExceptionEventArgs>(...);
There are two unexpected exception handlers that I'm aware of at this point:
System.Threading.Tasks.TaskScheduler.UnobservedTaskException for exceptions, stored in a task, that are not accessed before the task is garbage collected.
Application.Current.UnhandledException for exceptions propagating out of the UI thread.
I'm not aware of anything to catch exceptions propagating out of the thread pool, yet.
Situation
Well, as you can see below, I have a main App, creating a thread, which creates a bunch of background workers. When the RunWorkerCompleted is fired on some BG worker, I sometimes end up dropping an Unhandled Exception, (for a reason I have clearly pinpointed, but this is not the matter).
So the Logs clearly show that my UnhandledException handler is entered and reports the exception.
I know I am deliberately misusing the OnUnhandledException by stopping the App from exiting, using a Console.Read(). I did it on purpose because I want a human intervention/check before terminating the app.
public static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Logger.log("UNHANDLED EXCEPTION : " + e.ExceptionObject.ToString());
Mail.Sendmail("ADMIN ALERT : " + e.ExceptionObject.ToString());
Console.Read(); // Yes, this is an ungraceful trick, I confess.
}
However, what was supposed just to be a "pause" before manual exit turned out to keep the App alive, ie, the Thread is still generating workers, and running as if nothing happened.
Even Weirder : The UnhandledException is still being dropped from time to time when it happens again. And it is logged each time, behaving just as if it was a plain ol' try catch.
(This was the default behaviour before .Net 3.0)
Question
So, why is everything happening as if the UnhandledException was not thrown, and the thread and BG's keeping running as if nothing happened ? My guess is that as long as the OnUnhandledException handler is not done, and the App is still alive, all running threads that are still alive keep on living in a free world and doing their job.
This gives me a bad temptation, which is to keep this design, as a try/catch to unHandled Exception. I know this is not a tidy idea, as you never know if the exception is serious or something that could be skipped. However, I would really prefer my program to keep running all day and watch the log report / mail alerts and decide for myself if it needs to be restarted or not.
As this is a server application that needs to be running 24/7 I wanted to avoid ill-timed and repetitive interruptions due to minor still unhandled exceptions.
The biggest advantage to that being that the server program keeps running while we are tracking down unhandled exceptions one by one and deliver patches to handle them as they occur.
Thank you for your patience, and please feel free to give feedback.
PS : No, I did not smoke pot.
My guess is that as long as the OnUnhandledException handler is not
done, and the App is still alive, all running threads that are still
alive keep on living in a free world and doing their job.
Correct. But your other threads are now doing their job in a potentially unstable process. There are good reasons for terminating the App when an unhandled exception happens.
I would really prefer my program to keep running
Besides the (potential) stability problems, you would accumulate the halted state of whatever is involved in the unhandled handling. My guess is that you would at least leak a Thread each time it happens. And you can't spare too many of them.
So it would be a very bad design, and only delay the crashing.
First of all you need to subscribe the UnhadledThreadException handler. There you can not "Hijack" the exception, but you have access to it and also to the thread it belongs. What you can do now is putting the throwing Thread into suspetion. The Thread will be still alive!!
This however is a bad, dirty hack! Do not do this!
Take a look at this article for some details.
I recommend switching your threading model to TPL (design remains). There you have access to those ugly cross-thread excepions and can handle/supress em gracefully.
If you want to allow a BackgroundWorker thread to fail without killing the whole process, there's a cleaner way to do this.
First, intercept the RunWorkerCompleted event. This event is raised when the BackgroundWorker thread terminates, either normally or via an unhandled exception. Then in your event handler, check for the unhandled exception:
// Runs when the BackgroundWorker thread terminates.
private void ThreadFinished(object sender, RunWorkerCompletedEventArgs e)
{
// Process any unhandled exception
if (e.Error != null)
{
this.LogError(e.Error.Message, e.Error.StackTrace, blah, blah);
In this way, you can let the BackgroundWorker thread die and log any exception without terminating the whole process.
First some background: I have a multi-threaded WinForms application that is doing interop to native dlls. This application crashes sometimes with unhandled exception and we are trying to investigate why does it happen. In order to facilitate it, I am creating a global exception handler and I plan to generate process dumpfile from it.
Now coming towards question: as of now this application has handler for Application.ThreadException but it still crashes with unhandled exception. I am thinking of adding a handler for AppDomain.UnhandledException also although I am not sure if its going to help. Are there any possible unhandled exception in this scenario that will not be caught by Application.ThreadException?
Yes, Application.ThreadException can only trap exceptions that are raised in the UI thread. In code that's run due to Windows notifications. Or in technical terms, the events that are triggered by the message loop. Most any Winforms event fit this category.
What it does not trap are exceptions raised on any non-UI thread, like a worker thread started with Thread.Start(), ThreadPool.QueueUserWorkItem or a delegate's BeginInvoke() method. Any unhandled exception in those will terminate the app, AppDomain.UnhandledException is the last gasp.
Going further down-hill, hardware exceptions that are raised in an unmanaged thread by native code that never made any managed CLR call can not be detected with any CLR mechanism. An AccessViolation (exception code 0xc0000005) is the most common cause of death. The only way to trap those is through the Windows API, SetUnhandledExceptionFilter(). This is hard to get right.
You can disable Application.ThreadException with Application.SetUnhandledExceptionMode(). Which is a wise thing to do, giving the user the Continue option doesn't make a lot of sense. Now all exceptions in managed threads behave the same, use AppDomain.UnhandledException to log them.
Application.ThreadException will only be raised for unhandled exceptions on WinForms UI threads (see here.) Adding a handler for AppDomain.UnhandledException could help in this case (though with some caveats, as described in the remarks section here.)
I highly recommend that you use the OS minidump generation instead of your own. This is for several reasons:
Generating a minidump from within the same process is extremely problematic and not always possible.
By the time ThreadException or UnhandledException is started, the exception stack has already been unwound. Generating a minidump at that point will just point you to the handler, not the source of the exception.
If your app is in the field, use WER. If you're doing in-house testing, use ProcDump. You can also just copy the minidump file while the Error Reporting dialog is active.
P.S. There are some exceptional conditions - most notably when doing p/Invoke - where neither ThreadException nor UnhandledException will work.
P.P.S. If you have a debuggable scenario, then try turning on the Managed Debugging Assistants relating to p/Invoke.
I got TargetInvocationException while doing long process in another thread caused by a windows control on UI thread (Progress Bar). This exception leads my app to crash (goes to main method in debugging) and could not be caught by try catch.
I figured out what made this exception, and fix it (that was trying to assign “Value” property by a value that exceeds the maximum). But it made me wondering how I can catch exception like this (in production code) so I have an option to recover my application instead of terminating the application.
Chances are you aren't going to be able to recover very much. In terms of your operation, the state of a good number of stack frames (and objects referenced from those stack frames) is probably invalid because of the error.
Because of that, at best you can recover at a very high level and try the operation again.
If the resources you are accessing are able to be contained in a transaction, then I would suggest doing that, so that you don't have to worry about inconsistencies in persisted data.
Also, you might want to check out this thread on SO:
Best Practice for Exception Handling in a Windows Forms Application?
As well as the Exception Handling Application block from Microsoft:
http://msdn.microsoft.com/en-us/library/cc309505.aspx
You can 'handle' exceptions (really, you're just receiving notification of them) on the GUI thread via the static event Application.UnhandledException.
When you attach a handler to this event, it will be invoked for all unhandled exceptions on the WinForms UI (message pump) thread. The fact that you have this handler attached means that the Application won't exit. Without it, WinForms shuts down your application.
Catch the exception and find a mechanism to pass it back to the main or calling code.
Not sure what version of .net you are using if its 3.0+ you can do something along these lines.
private void UpdateValue(int newValue)
{
Action myAction = () => progressBar.Value = newValue;
if (progressBar.InvokeRequired)
progressBar.Invoke(myAction);
else
myAction();
}
Call this method with the new value for the progress bar it will check if the call needs marshalling and make the appropriate call. Be careful InvokeRequired is relatively expensive, so use it only where needed. You could make this into an extension method to make generic use of this pattern for other controls if needed.
Hope this helps.