How can an application be properly crashed? - c#

I have a handler for unhandled exceptions in the App class of my project. It is for the purpose of setting up a Send Feedback button.
App.xaml.cs
private void Application_DispatcherUnhandledException(
object sender, DispatcherUnhandledExceptionEventArgs e)
{
try
{
// Try to collect feedback with dialog.
new ApplicationExceptionDialog(e).ShowDialog();
}
catch
{
MessageBox.Show(
"A problem has occurred with the program:\r\n\r\n" +
e.Exception.Message + "\r\n\r\n" +
"The application will now exit.",
"Application Error",
MessageBoxButton.OK,
MessageBoxImage.Error);
}
finally
{
Application.Current.Shutdown(1); // ← Is this okay?
}
}
Question
Other than handling various exceptions, when all else has failed, what is the proper way to exit the application after an unhandled exception?
Edit
This question is specific to WPF applications. I also have unmanaged code in the application to make logins more secure. I haven't had any problems with it, but I need to make sure that if problems arise, the exit process used is the best option.

The proper way to close a WPF app is to use Application.Shutdown. This instructs all message pumps to stop, and allows your clean-up code (such as closing events) to execute. It also leaves all non-background threads running. In your case, this is probably not what you want.
Since you have an unhandled exception, your system is in an unknown state - you can't assume your closing events will run correctly, and that any running threads will gracefully terminate. As such, I'd suggest using Environment.Exit, this will close the process, and all of it's running threads. But it will run your finally blocks and class finalizers, which are typically used to release acquired resources.
If you think that running finalizers in the current state may result in existing data/resource corruption, or poses any other kind of damage to the system, you should use Environment.FailFast instead. This will instruct the OS to simply kill your process immediately, without running any finalizers. You may want to use this over Environment.Exit, depending on the purpose of your application.

To exit a console application try
Environment.Exit(0);
For a windows application try:
Application.Exit(0);

Related

Hijacking UnhandledException to keep Multi-Threaded Application Running

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.

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.

How to properly unload an AppDomain using C#?

I have an application that loads external assemblies which I have no control over (similar to a plugin model where other people create and develop assemblies that are used by the main application). It loads them by creating new AppDomains for these assemblies and then when the assemblies are done being used, the main AppDomain unloads them.
Currently, it simplistically unloads these assemblies by
try
{
AppDomain.Unload(otherAssemblyDomain);
}
catch(Exception exception)
{
// log exception
}
However, on occasion, exceptions are thrown during the unloading process specifically CannotUnloadAppDomainException. From what I understand, this can be expected since a thread in the children AppDomains cannot be forcibly aborted due to situations where unmanaged code is still being executed or the thread is in a finally block:
When a thread calls Unload, the target
domain is marked for unloading. The
dedicated thread attempts to unload
the domain, and all threads in the
domain are aborted. If a thread does
not abort, for example because it is
executing unmanaged code, or because
it is executing a finally block, then
after a period of time a
CannotUnloadAppDomainException is
thrown in the thread that originally
called Unload. If the thread that
could not be aborted eventually ends,
the target domain is not unloaded.
Thus, in the .NET Framework version
2.0 domain is not guaranteed to unload, because it might not be
possible to terminate executing
threads.
My concern is that if the assembly is not loaded, then it could cause a memory leak. A potential solution would be to kill the main application process itself if the above exception occurs but I rather avoid this drastic action.
I was also considering repeating the unloading call for a few additional attempts. Perhaps a constrained loop like this:
try
{
AppDomain.Unload(otherAssemblyDomain);
}
catch (CannotUnloadAppDomainException exception)
{
// log exception
var i = 0;
while (i < 3) // quit after three tries
{
Thread.Sleep(3000); // wait a few secs before trying again...
try
{
AppDomain.Unload(otherAssemblyDomain);
}
catch (Exception)
{
// log exception
i++;
continue;
}
break;
}
}
Does this make sense? Should I even bother with trying to unload again? Should I just try it once and move on? Is there something else I should do? Also, is there anything that can be done from the main AppDomain to control the external assembly if threads are still running (keep in mind others are writing and running this external code)?
I'm trying understand what are best practices when managing multiple AppDomains.
I've dealt with a similar problem in my app. Basically, you can't do anything more to force the AppDomain to go down than Unload does.
It basically calls abort of all threads that are executing code in the AppDomain, and if that code is stuck in a finalizer or unmanaged code, there isn't much that can be done.
If, based on the program in question, it's likely that the finalizer/unmanaged code will finish some later time, you can absolutely call Unload again. If not, you can either leak the domain on purpose or cycle the process.
Try to make GC.Collect() if you do not unload the domain.
try
{
AppDomain.Unload(otherAssemblyDomain);
}
catch (CannotUnloadAppDomainException)
{
GC.Collect();
AppDomain.Unload(otherAssemblyDomain);
}
I had similar issues with random behavior for months now, (with some app.Unload even BLOCKING forever ! on some machines)
finally decided to take a big breath and made process isolation.
you can spawn child console process and redirect output
if you need to cancel this is finger in the nose to kill child process and all dependencies / handles.
To an extreme i had to run dedicated cleanup code, and came to solution to create additional process with dedicated cmd line waiting input extracted from console output of initial runner process.
yes this app domain is a real joke and i think this is not a coincidence that it is not anymore in net core.

Ways to kill a running program and how to trap them?

We have different ways to kill a running C# program.
ctrl + C;
task bar then right click its icon, then select 'close' on the popup;
task manager, select the its executable name and then click end process;
console window, use kill command;
maybe more.
What I am asking here is how handle them in my C# program to guarantee my C# program exit gracefully when possible. I know how to trap ctrl + C, but don't the others. can you help me? thanks,
The best guarantee you have at code being run at exit is the finally statement.
Note though that your program will have to run in the try block when you use this mechanism.
I believe that the only time the block inside the finally is not executed are at:
A StackOverflowException;
Corrupted state exceptions (from .NET 4);
Forceful termination through the task manager (an unmanaged process kill);
Crash of the entire system (removing the power cable e.g.).
See Keep Your Code Running with the Reliability Features of the .NET Framework for an in depth analysis.
Scenario 2 basically calls Application.Exit(), which should amount to a graceful shutdown of all threads associated with your process. It also fires events you can use to perform any additional cleanup.
3 and 4 can be "trapped" by attaching a handler to the Application.ThreadException event of a WinForms app. This event is fired when any exception is about to be thrown out of the program to be handled by the runtime (which will terminate your assembly's execution and clean the sandbox). However, at this point there's very little you should do other than write something to the Event log or clean up any statics, like an IoC container or repository, and even that's problematic because if one of those objects caused the exception, you could very easily throw another exception in trying to deal with the last one.
Basically, if your user is using "kill" or "End Process" to close your app, there's something VERY wrong and you should probably address the underlying reason why a user would be doing that, before trying to gracefully capture such termination behaviors.
Cannot trap. You cannot avoid killing of a program. But you can always subscribe to kill. Just imaging how you can trap when people pull the power plug...
.NET 2.0
Subscribe to the AppDomain.CurrentDomain.ProcessExit event
.NET 3.5
Application.Exit Event
Useful links
AppDomain.CurrentDomain.ProcessExit and cleanup
How to detect when application terminates?
How to detect when main thread terminates?

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