views:

4805

answers:

4

I have a console application that contains quite a lot of threads. There are threads that monitor certain conditions and terminate the program if they are true. This termination can happen at any time.

I need an event that can be triggered when the program is closing so that I can cleanup all of the other threads and close all file handles and connections properly. I'm not sure if there is one already built into the .NET framework, so I'm asking before I write my own.

I was wondering if there was an event along the lines of:

MyConsoleProgram.OnExit += CleanupBeforeExit;
A: 

There is for WinForms apps;

Application.ApplicationExit += CleanupBeforeExit;

For Console apps, try

AppDomain.CurrentDomain.DomainUnload += CleanupBeforeExit;

But I am not sure at what point that gets called or if it will work from within the current domain. I suspect not.

Rob Prouse
The help docs for DomainUnload say "The EventHandler delegate for this event can perform any termination activities before the application domain is unloaded." So it sounds like it does work within the current domain. However, it may not work for his need because his threads may keep the domain up.
Rob Parker
+11  A: 

I am not sure where I found the code on the web, but I found it now in one of my old projects. This will allow you to do cleanup code in your console, e.g. when it is abruptly closed or due to a shutdown...

[DllImport("Kernel32")]
private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add);

private delegate bool EventHandler(CtrlType sig);
static EventHandler _handler;

enum CtrlType
{
  CTRL_C_EVENT = 0,
  CTRL_BREAK_EVENT = 1,
  CTRL_CLOSE_EVENT = 2,
  CTRL_LOGOFF_EVENT = 5,
  CTRL_SHUTDOWN_EVENT = 6
}

private static bool Handler(CtrlType sig)
{
  switch (sig)
  {
      case CtrlType.CTRL_C_EVENT:
      case CtrlType.CTRL_LOGOFF_EVENT:
      case CtrlType.CTRL_SHUTDOWN_EVENT:
      case CtrlType.CTRL_CLOSE_EVENT:
      default:
  }
}


static void Main(string[] args)
{
  // Some biolerplate to react to close window event
  _handler += new EventHandler(Handler);
  SetConsoleCtrlHandler(_handler, true);
  ...
}
flq
Can you use this to cancel the exit? Other than for when it's shutting down!
ing0
james, I have no idea but the Handler signature returns a bool, so I'd try out what happens when you return true/false
flq
This works great, only `bool Handler()` must `return false;` (it returns nothing in the code) so it would work. If it returns true, windows prompts "Terminate Process Now" dialog. =D
Cipi
+1  A: 

It sounds like you have the threads directly terminating the application? Perhaps it would be better to have a thread signal the main thread to say that the application should be terminated.

On receiving this signal, the main thread can cleanly shutdown the other threads and finally close itself down.

Rob
I have to agree with this answer. Forcing application exit and then trying to clean up afterward isn't he way to go. Control your application, Noit. Don't let it control you.
Randolpho
A thread spawned by me directly isn't necessarily the only thing that can close my application. Ctrl-C and the "close button" are other ways that it can end. The code posted by Frank, after minor modifications, fits perfectly.
ZeroKelvin
+2  A: 

Check also:

AppDomain.CurrentDomain.ProcessExit
jmservera