How to allow IErrorHandlers to handle AccessViolationExceptions in WCF? - c#

Sure, we must avoid catching and attempting to handle AccessViolationExceptions(AVEs). However, in my current case, the exception is thrown from a COM+ managed component which terminates the process that threw the exception, therefore, cleaning up correctly. However, a windows service, hosting WCF, that consumes said COM+ component receives the bubbled up AVE causing the service crash.
The IErrorHandlers in place don't seem to fire/detect AVEs.
Is there any way to enable WCF IErrorHandlers to catch AVEs?

As a variant you can try to add a handler on AppDomain.CurrentDomain.UnhandledException where you can restart a service again.
Or, you can run your main win_service in one ('Main')AppDomain and host the WCF service in another ('Sub')AppDomain. In such way you can unloaded(reload) the sub-proccess without affecting the main process.

It is not possible for IErrorHandlers to catch exceptions similar to AccessViolationExceptions (SEHExceptions).

Related

Application.ThreadException on WCF Service?

I canĀ“t find a Application.ThreadException event to listen to on my WCF service. I suppose that this is for WinForms so is there a ThreadException event for WCF services? Or will they end up in AppDomain.CurrentDomain.UnhandledException?
The Application.ThreadException event is only used to "to handle otherwise unhandled exceptions that occur in Windows Forms thread" (emphasis added, MSDN), so it isn't of much help in a WCF service.
Your best bet is to indeed use AppDomain.CurrentDomain.UnhandledException. Note however, that you cannot prevent the process from exiting. This event merely allows you to do some logging or error reporting, before "the system default handler reports the exception to the user and terminates the application." (MSDN).
You many also want to implement your own IErrorHandler. Also, checkout this blog entry about some WCF error handling best practices, while your at it.
It looks like you'll need to implement IErrorHandler:
http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.ierrorhandler.aspx
Then register your handler with your ServiceHost:
http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.channeldispatcher.errorhandlers.aspx
It looks like you can also wire up the IErrorHandlers using a custom attribute as described here: http://msdn.microsoft.com/en-us/library/ms751439.aspx
It depends on your client framework.
WCF faults get thrown as exceptions on the client side, so handle them like any other global exception handler:
Winforms uses
Application.ThreadException
WPF uses:
Application.DispatcherUnhandledException
As Christian states, these are only for exceptions thrown on the "GUI" thread, but WCF will marshal callbacks on a duplex service to these by default I think.

Any way to catch exceptions from any spawned thread?

I am developing an app that has plugin support. Plugins may be developed by third parties.
Currently I have a try/catch handler around any calls into the plugins to try and protect my app from third party code. The catch logs the problem but does not crash my app.
My problem is when the third party code spawns threads to do some work. These are not caught by my handler.
Is there any way to catch exceptions from "anything spawned by this function"? Or do I need to just catch them in my global handler?
When an plugin fails and runs within the same AppDomain, it is best to let the application fail itself; thus, stop the application. You won't know in what state the application is when a plugin crashes.
Another option is to run a plugin in its own (child) AppDomain. This way you can unload that app domain and restart that plugin in a newly created AppDomain, without having to restart the application.
You might want to take a look at the Managed Extensibility Framework (MEF). That is especially designed for these scenarios.
Regarding your second wish - catching the exception in a global handler, you can subscirbe the the UnhandledException event in the application domain. It'll catch all exceptions that were not caught in your code.
It is used mainly to log the information of the exception. It won't, however, save your application from terminating.

Catching all crashes in C# .NET

There are already some pretty good threads on this topic on Stack Overflow, but there doesn't really seem to be a concise answer on any of them. My C# console application (running as a Windows service) launches a Java process and manages it (starts/stops/restarts it), but my issue is that I will remote into machines, and see it has started about 20 Java processes sometimes.
This is obviously an issue with my application crashing at some point, and not shutting down the Java process it started. I have hooked "UnhandledExceptionEventHandler" in the AppDomain.CurrentDomain, and I call TerminateProcess() from it (shuts down the active Java process) but this issue is still occuring on occassion.
My application has the Main thread, a TCP Server Thread (which accepts async connections), and a UDP Server Thread. Is there anything else I should be hooking into on top of UnhandledException?
EDIT
It also just occured to me that I have a few Try/Catch blocks in my code that simply write to console, which I never see. Should I just remove these so these are caught by the UnhandledException or add a logger there instead?
First of all you have to change the Console.WriteLine.. lines in you code to Debug.WriteLine.. if you don't want to log, so the output of it will only be on debug.
Second when any exception occurs if you don't know how to handle it or fix it then rethrow it catch { throw; } after logging. I personally do
try
{
...
}
catch (Exception exception)
{
Log(exceptiosn);//log it first or Debug.WriteLine...
#if DEBUG
System.Diagnostics.Debugger.Break();//break at the debugger here.
#endif//DEBUG
throw;
}
After you cleaning up you code, now you can whenever DomainUnhandledException thrown, you can restart your application. an example will be here, The idea is you start a new instance from your application and then terminate the first one. you also define a mutex so only one instance at time will be alive.
Something to consider is whether you want the .NET application to be responsible for the spawned processes. If possible, they might be made responsible for shutting down when no longer receiving input. If the spawned processes are running on other machines I would try to do that anyway because network problems might interfere with sending a shutdown message from the .NET application to the Java processes. Each its own responsibilities.
That said, getting exception handling in the .NET application fixed (especially when you are missing some exceptions) is also important. Make each thread responsible for its exceptions and make sure you log them for easy debugging.

Out of memory exception - Windows service stop

I have a timer within my Windows service which is built using C# 2.0. We are in the process of designing the Exception handling. Since it is Timer runs on its own thread we would like to handle the out of memory exception. When that occurs we would like to stop the service. How can we gently stop the service when that happens on the different thread ?
OutOfMemoryException is never supposed to be "handled" by your application. You should start to troubleshoot if there is any memory leak immediately and resolve the leaks.
Use the service control manager API to send your own service a "stop" command? That would allow your standard functionality for handling that command to be invoked.

Avoid "program stopped working" in C#/.NET

I have a console application written in C#/.NET that I want to run from a script (nant). If an exception occurs in the console application, I would like nant to continue, but in Windows Vista there is a popup that searches for solutions and asks for debug etc.
I would like to avoid the popup with "program stopped working" when an exception happens in the console application. How can I control this from C#/.NET?
(A similar question addresses the issue for the C language, but I would like a solution for C#/.NET.)
(To clarify: I would like the exception to be passed to nant, but without the popup.)
The JIT debugger popup occurs when there's an unhandled exception. That is, an exception tunnels all the way up the stack to the root of any thread in the runtime.
To avoid this, you can handle the AppDomain.CurrentDomain.UnhandledException event and just call Environment.Exit(1) to exit gracefully.
This will handle all exceptions on all threads within your AppDomain. Unless you're doing anything special, your app probably only has one AppDomain, so putting this in your public static void Main method should suffice:
AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
{
Console.Error.WriteLine("Unhandled exception: " + args.ExceptionObject);
Environment.Exit(1);
};
You should probably use the NAnt logger to write out the error in this case too (can't recall the API for this offhand though.)
You can also disable JIT debugging on the machine. I would only recommend this in certain circumstances such as for a dedicated build server.
Under Windows Vista you can disable this dialog for your programms.
Disable the "Problem Reports and Solutions feature". You find it under Control Panel-->Problem Reports and Solutions-->Change Settings-->Advanced Settings-->Turn off for my programs, problem reporting
Just catch the exception and log/ignore it.
The popup appears due to an unhandled exception. To avoid that make sure your main method captures all exceptions and turn them into some other useful piece of info you can pick up. Just ignoring the exception is not recommended.
Btw remember that exceptions are per thread, so if your application spawns threads or uses thread pool threads, you need a handler for these too.
Usually this only happens when your app doesnt handle an exception. If you wrap your whole console app in a try/catch bblock, and just pass back a fail code, then you will avoid this.
Sometimes, a windows application will stop working if you are using a System.Timers.Timer.
To fix this, change System.Timers.Timer by System.Windows.Forms.Timer
Greetings

Categories