5

We have different ways to kill a running C# program.

  1. ctrl + C;
  2. task bar then right click its icon, then select 'close' on the popup;
  3. task manager, select the its executable name and then click end process;
  4. 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,

5YrsLaterDBA
  • 33,370
  • 43
  • 136
  • 210
  • Why? What are you trying to do? – SLaks Nov 15 '10 at 16:33
  • 3
    "gurantee my C# program exit gracefully" you cant. – Aliostad Nov 15 '10 at 16:34
  • What technology? WinForms, Console, WPF? – Pieter van Ginkel Nov 15 '10 at 16:36
  • possible duplicate of [Capture console exit C#](http://stackoverflow.com/questions/474679/capture-console-exit-c) – flq Nov 15 '10 at 16:38
  • 1
    A user often attempts to 'kill' a process because it is unresponsive and / or misbehaving. In this case, the OS respects the user more than it does the process and may not be polite enough to inform it of its impending death. This is the correct thing to do. – Ani Nov 15 '10 at 16:39

3 Answers3

4

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.

Pieter van Ginkel
  • 29,160
  • 8
  • 71
  • 111
  • With the .NET 4 runtime `finally` blocks are skipped for Corrupted State Exceptions as well. – Brian Rasmussen Nov 15 '10 at 16:43
  • @Brian Rasmussen - Thank you very much; added to the answer. – Pieter van Ginkel Nov 15 '10 at 16:46
  • One major case you missed is if code in the finally block throws its own exception. This is particularly bad, because not only are you not executing any statement after the exception is thrown, you are effectively masking any exception thrown from the try/catch portions, because the runtime now has to deal with this new exception before returning to the unwind of the old one. – KeithS Nov 15 '10 at 16:48
  • @KeithS - That is correct, however, the `finally` block has run (up until that point) and any other `finally` blocks higher up the stack will get run, right? I feel that this falls under the category "you had your chance" :). – Pieter van Ginkel Nov 15 '10 at 16:50
0

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.

KeithS
  • 70,210
  • 21
  • 112
  • 164
0

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?

Community
  • 1
  • 1
A G
  • 21,087
  • 11
  • 87
  • 112
  • Also [AppDomain.CurrentDomain.UnhandledException](http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx) – Brian Nov 15 '10 at 16:52