We have an interface IPoller for which we have various implementations. We have a process that will take an IPoller and start it in a separate thread. I'm trying to come up with a generic way of providing exception handling for any IPollers which don't do it themselves.
My original thinking was to create an implementation of IPoller that would accept an IPoller and just provide some logging functionality. The question I ran into though is how would I provide this error handling? If I have IPoller.Start() which is the target for the Thread is that where the exception will occur? Or is there something on the thread itself I can hook into?
Something like:
Thread thread = new Thread(delegate() {
try
{
MyIPoller.Start();
}
catch(ThreadAbortException)
{
}
catch(Exception ex)
{
//handle
}
finally
{
}
});
This will ensure the exception doesn't make it to the top of the thread.
You should catch the exception at the method you use at the top of the thread, and do the logging from there.
An unhandled exception (at the top of a thread) will (in 2.0 onwards) kill your process. Not good.
i.e. whatever method you pass to Thread.Start (etc) should have a try/catch, and do something useful in the catch (logging, perhaps graceful shutdown, etc).
To achieve this, you could use:
static logging methods
captured variables into the delegate (as an anonymous method)
expose your method on an instance that already knows about the logger
In .NET 4.0+ you should use Tasks instead of threads. Here's a nice article on exception handling in Task Parallel Library
Take a look at AppDomain.UnhandledException, it will help you at least log those exceptions that you are not handling, and in some cases close down "nicely":
This event provides notification of
uncaught exceptions. It allows the
application to log information about
the exception before the system
default handler reports the exception
to the user and terminates the
application. If sufficient information
about the state of the application is
available, other actions may be
undertaken — such as saving program
data for later recovery. Caution is
advised, because program data can
become corrupted when exceptions are
not handled.
Have a look at
Appdomain.FirstChanceException event
It tells you moment any exception occurs and CLR is looking for stack trace. Also event args tell which type of exception. You can consider it as the central place for logging.
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.
I'm in the needing of write a custom exception handler...
MY application is probably going to throw different kind of exceptions, and I would like they all get handled by a single handler (so that I don't need to use thousands of "try-catch" blocks).
I tried with the AppDomain's UnhandledException handler, but it seems that, when an exception is caught, the application will inevitably be closed.
So, is there any way I could accomplish my idea?
EDIT:
Thank you for your rapid replies, but I'd like to make you understand better my situation: I have, for example, a class which throws a custom exception (reversible). Now, this class, is called by multiple other class, so I would need to write a try-catch block on every single one of them (or at least this is what your replies make me think about)..
So, here comes the needing of have an handler capable of catch them all...
You should catch specific exceptions at the point in your code where you are best able to handle them. This should not result in thousands of try-catch blocks, rather, you should find localised areas of exception handling.
I tend to handle exceptions at service boundaries, for example, when interacting with databases or file-systems. At these service boundaries you can handle an exception and perform some logical recovery.
If you find yourself writing try-catch blocks where the catch does not add value, does not help your code recover, then you are not adding value by catching the exception!
You shouldn't need 'thousands' of try/catch blocks.
Only catch what you understand at the points where you can make a decision.
Catching an exception is very much part of your logic (unlike try/finally) and using 1 central handler usually won't do.
Consider this as an opportunity to study the proper use of exceptions.
You can use the AppDomain's UnhandledException Handler without closing the application. I do it too to log missed exceptions:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Program_UnhandledException);
And
private static void Program_UnhandledException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
//Handle the exception here...
}
Yet I do agree with the other answers, usually you shouldn't need a catch all exception handler. Handling exceptions where they occur should be the preferred action.
Edit: I don't know if it works the same way in console applications too.
Wrap your code in a try and catch block, which catches a Exception. All Exceptions are derived from Exception, so every exception that is thrown and not handled elsewhere is caught here. But remember if an exception is thrown, you deal with a possible invalid state of your application. You can't just always continue after an exception.
Another, rather direct approach is to register to the Application.ThreadException(WinForms) but again, you should not use this if you plan to continue running the application. This is for cases where you want to display a message, maybe a way to send the error report and then close the application.
try
{
// Code that needs exception handling
}
catch (Exception ex)
{
// Handle exception. You may use ex.GetType()
}
If this is not adequate, please explain why in your question.
We have UnhandledExceptionEventHandler in place and unexpected exceptions were caught by that handler. But why we still see the following screen? I thought if we handled the exception, it will not go up to the OS. If no exception reach the system level, why that screen still show up?
Registering an UnhandledExceptionEventHandler with AppDomain.UnhandledException does not mean that unhandled exceptions become handled. Instead, it is a mechanism to be able to log the exception and relevant program state to aid in later debugging. The exception will remain unhandled and Windows Error Reporting will be invoked.
In reality, when this event is invoked it's "too late" for the the exception to be handled. Assuming you could tell the runtime to continue execution, where would execution unwind to? Not a single frame on the call stack wanted to handle the exception. At best, the executing thread could be terminated; but what if it's on the only foreground thread? Better to propagate the unhandled exception to the operating system's default unhandled exception filter and let it invoke Windows Error Reporting.
Edit with some additional comments:
Now, certain applications you want to design to be crash-resistant, such as long-running service processes. It may make sense to add "catch-all"* exception handlers in some cases, such as a job queue that executes jobs and it doesn't matter if an individual job fails with an unhandled exception; we log the problem and move on to the next job. However, a root catch-all handler in something like Main makes little sense: your entire application is now in an unknown state. You could log the exception and terminate, but you'd be missing out on the benefits of Windows Error Reporting: post-mortem minidumps and an easy button (the "Debug" button on that dialog) to invoke the registered JIT debugger that will take you directly to the problem. For most software, my advice is to simply let your software crash; in-your-face bugs with minidumps are usually some of the easiest to fix.
*Some exceptions are inherently "uncatchable", such as a StackOverflowException. Others, such as an AccessViolationException are catchable, but are inherently indicative of a serious program state incongruity (couldn't read or write from an expected memory location). It is never a good idea to attempt recovery from such exceptions.
Click the Debug button to see where the exception comes from.
If you don't see it immediately, start your application in Visual Studio, go to the Debug,Exceptions dialog, and check all exceptions. Then rerun your application, investigate the code every time the debugger tells you that a first-chance exception has been encountered, and pass the exception to the application if Visual Studio asks you whether to do this.
This should help you finding the source of the problem.
That's because your unhandled exception occurs in the main thread, and there is almost nothing to do about it. Check this article: What!? A .NET Application Can Die?
Almost nothing, yes, because you can still catch that exception on the Application.Run level. At this point your application is dead anyway, but at least you can "avoid windows crash screen" and implement your own crash screen instead:
static void Main()
{
try
{
Application.Run(new Form1());
}
catch (Exception ex)
{
MessageBox.Show("Oops! Can I has " + ex.Message + "?");
}
}
There are cases when unhadled exceptions will not be handled by UnhandledExceptionEventHandler. For example System.Timers.Timer is swallowing exceptions, so they are not propagated to UnhandledExceptionEventHandler.
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.