I am using system.timer in a windows service application (c#) and have added:
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(MyExceptionHandler);
To handle my exceptions, does this work in a Windows Service as it does not seem to work?
Does anyone have any alternative ideas?
This mechanism will work to capture Unhandled Exceptions in any environment including Windows Services. However there are some limitations on what kind of exceptions can be handled in this way. For instance, a StackOverFlowException may be unhandled but do to it's nature you won't ever see it go through an UnhandledException handler.
Why do you think this is not working? Have you tried attaching to the process with a debugger , enabling first chance exceptions and see what is going on?
Why do you have an unhandled exception in a service? What is the exception? Some exceptions have "special behavior" (and another link here for .NET 4 changes to corrupted state exceptions).
Also, what are you trying to do in the handler? Maybe the actions you're trying to do in the handler are what's limited when running as a service.
Related
I'm trying to catch all unhandled exceptions in my app in order to conditionally handle those that can be without terminating the app, but I cannot solve a very basic problem: it doesn't stop the exception. An unhandled exception is thrown somewhere in the code, it comes here, the message box is shown, and then the application either shows that the same exceptions was unhandled (if in debug mode) or just crashes (if run without debugging). Meaning that the exception stays unhandled even though the handler was called.
App() {
AppDomain.CurrentDomain.UnhandledException += (s, a) => {
var ex = (Exception)a.ExceptionObject;
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
};
}
This is from a new, blank test project that has nothing in it but this code and a button that throws exception when clicked.
You are forgetting to terminate your program. So it continues on with the normal unhandled exception handling. Add this line:
Environment.Exit(System.Runtime.InteropServices.Marshal.GetHRForException(ex));
The slightly laborious Marshal call ensures that another process that obtains the Process.ExitCode for your process gets a reasonable error indication. It is optional, merely recommended.
From MSDN:
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.
In other words, it's just a handler to allow you to tell the user what happened, produce last minute save information if you need to be able to recover data, or do something like fire off a custom error report. It is not a catch block. To catch exceptions you have to use Try-Catch.
If this is really the behaviour that you want you could add the following to your application configuration file:
<legacyUnhandledExceptionPolicy enabled="1"/>
See Exceptions in Managed Threads.
It is not supposed to "stop" the exception, that behavior is by design:
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.
Consider this the place were nobody else has bothered to handle the exception in question, there is nothing sensible left to do but log and die.
You should deal with those exceptions that should terminate the application closer to where they occur.
You aren't actually catching the unhandled exceptions but merely handling an event that occurs right before terminating the application (in release mode). Subscribing to this event doesn't count as catching an already unhandled exception.
From MSDN:
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.
When writing for ASP.NET and, while the debugger is attached, if you visit a web page that throws an exception, the unhandled exception helper is launched at the line of code that caused the exception.
This occurs even if you only are catching unhandled exceptions and are not catching thrown exceptions. However, hitting F5, ignoring the exception, or not having the debugger attached does not cause the AppDomain to be torn down. Instead somehow ASP.NET handles the unhandled exception anyway.
How does this work, and can exception handling like this be implemented elsewhere so that other unhandled exceptions can be swallowed rather than kill the whole AppDomain or process?
Edit: To clarify, I understand how exception handling and try...catch blocks work. However, in this case it seems that the debugger is considering the exception unhandled while at the same time ASP.NET is wrapping the exception in a try...catch. That is the behavior I want to emulate.
How does this work,
asp.net just wraps executing code in whatever exception-handling code they want. asp.net webpage (or view, or controller) is just a class, and how to use it is entirely up to host (in our case, asp.net).
why does VS debugger break on it if it's handled?
There's a quote from MSDN documentation:
ASP.NET has a top-level exception handler that handles exceptions to show error pages to browser users. That top-level exception handler will stop an unhandled exception from breaking into the debugger unless Just My Code is turned on. Make sure that you enable Just My Code for ASP.NET debugging.
Which means that if you have "Just my code" enabled in VS Debug options (and it's enabled by default) you'll break at exceptions that are unhandled in your own code, irregardless of whether they are handled in your caller or not.
can exception handling like this be implemented elsewhere so that other unhandled exceptions can be swallowed rather than kill the whole AppDomain or process?
You can't do that, it is a security measure.
Your webpage is just a bunch of method calls from IIS & the ASP.NET Runtime, you're webpage isn't running alone in your appdomain. The code calling into your code has an ordinary try/catch block around that method call.
You could create a similar setup yourself:
For a ConsoleApplication, by placing a try/catch block around eveything in Main, meaning that you'l catch any exceptions that aren't handled elsewhere in your app.
For a Windows Forms application, by handling the Application.ThreadException event (Which allows you to hook into Windows Forms' message loop's try/catch block)
For a WPF appliaction, by handling the Application.DispatcherUnhandledException event (Which allows you to hook into WPF's message loop's try/catch block)
... or maybe you could use the AppDomain.UnhandledException event
The problem with these kinds of programs then would be: Where in the app should you continue?
The last question is solved easily in ASP.NET, since every page call is isolated from each other. The user just continues by navigating to a page again.
I am writing a multi-threaded application that relies on some third party DLLs. My problem is that when using an object from the third party library, if it raises an exception while running, I am unable to catch it and it bubbles up and kills the entire application. I have many different threads each using its own object from this third party library and I need the thread that was using that copy of the object to be able to catch and deal with the exception.
Based on what I've read, it seems like most likely the 3rd party library is actually making its own threads and allowing uncaught exceptions. The .NET 2.0+ behavior allows these exceptions to kill the entire application. I'm aware of AppDomain.CurrentDomain.UnhandledException, but that does not allow you to prevent application shutdown.
For reference, I'm writing a console application in .NET 4.0. Does anyone have any solution/advice to stop these exceptions from killing my application?
One thing you might look at is the HandleProcessCorruptedStateExceptionsAttribute attribute.
I don't know if this is your problem or not, but I had to recently use this attribute on a method that was calling a function in a third party COM object. This attribute is new to .net 4.0. My basic understanding is that the 4.0 framework will by default not bubble up an exception thrown in certain situations where it feels the 3rd party exception may have introduced some instabilty. I think this pertains mostly to situations where the 3rd party component is unmanaged. I am not sure, but it resolved my issue.
The usage looks like this:
[System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute()]
private void ThirdPartyCall()
{
try
{
return Call3rdPartyFunction()
}
catch (Exception exInstantiate)
{
...
}
}
More information: http://msdn.microsoft.com/en-us/magazine/dd419661.aspx
The issue is probably that exceptions thrown on background threads are not caught once they bubble out of the thread proc.
This seems like a non-obvious duplicate of How to prevent an exception in a background thread from terminating an application?
You can stop application crash by doing this:
AppDomain.CurrentDomain.UnhandledException += (sender, e2) =>
{
Thread.CurrentThread.Join();
};
But uncaught exception from 3d party components mean that components don't do their job properly. If you don't care if they don't do the job better don't use them.
after doing some research it seems that AppDomains are not really a tool for building a hosting server. From my understanding, the hosting server will still crash if there is an unhandled exception in a created AppDomain (if the exception is thrown from a thread in the created AppDomain). So in that case if the hosting server hosts a service which leaks exceptions this will bring down the default AppDomain as well.
So I guess from a server architecture point-of-view there is nothing better than creating child processes and monitoring them.
Is that correct or am I missing something with AppDomains?
thanks,
Christoph
If you can control the threads created in the other AppDomain, you can also handle exceptions by using catch-all blocks in the thread main method.
Other than that, as long as you use the default host, I believe that your assumption is correct. However, if you host the runtime yourself, you can also handle unhandled exceptions.
From a forum post on the topic:
Well, it is possible. You'd have to
create your own CLR host. That starts
with ICorBindToRuntimeEx(). You get
to have full control of AppDomains
that throw exceptions. And it's being
used by MSFT software like ASP.NET and
SQL Server 2005. When you write a
service, you are working with the
default CLR host implementation and it
terminates the process when any
unhandled exception is raised,
regardless of what AppDomain caused
the exception.
Problem is, hosts like ASP.NET and SQL
server have a very well defined code
execution path. In a web server,
managed code runs because of a page
request. In a dbase server, it runs
because of a query. When something
bad happens, they have the luxury of
simply aborting everything that the
request started (killing the
AppDomain) and returning a "sorry,
couldn't do it" status back to the
client. You might have seen it,
crashing the forums server on the old
web site was pretty trivial but didn't
stop it from serving other requests.
Not actually 100% sure about that.
Your service implementation is
probably not nearly as clean. I can't
tell, you didn't say anything about
it. It general, there's a problem
with aborting a thread. You always
have to abort a thread when there's an
unhandled exception. A service
typically has one thread, started by
the OnStart() method. Aborting it
kills the server until somebody stops
and starts it again.
You can definitely make it more
resilient than that, you could start a
"master" thread that launches child
threads in response to external events
that makes your service do its job.
Having a child thread terminated
because of an unhandled exception is
something you could possibly recover
from. But then, if you make that next
step, why not have the child thread
catch an exception and pass it back to
the master thread so it can make an
intelligent decision about what to do
next.
The cold hard fact of the default CLR
host is: if you are not willing to
deal with failure, it is not going to
do the job for you. And it shouldn't,
the .NET 1.x behavior to threads that
died with exceptions was a major
mistake that got corrected in .NET
2.0.
You know what to do: handle failure.
Or write you own host. Or accept that
things could be beyond your control
and log a good error message so you
can tell your customer what to do.
I'd strongly recommend the latter.
I'm currently writing a server that hosts several modules. The server runs each module in a separate AppDomain. What I want to achieve is exception isolation, i.e. when one module throws an exception I don't want whole process to terminate, just this specific AppDomain. I know that I can tell CLR to fallback to old behaviour (.NET 1.0) when all uncaught exceptions in different threads were swallowed. However, this is not the most 'elegant' solution.
How about subscribing to this event:
AppDomain.CurrentDomain.UnhandledException
You'll have to cast the ExceptionObject property from type Object to Exception.
Hope that helps.