Asked  7 Months ago    Answers:  5   Viewed   36 times

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;

 Answers

28

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:
          return false;
  }
}


static void Main(string[] args)
{
  // Some biolerplate to react to close window event
  _handler += new EventHandler(Handler);
  SetConsoleCtrlHandler(_handler, true);
  ...
}

Update

For those not checking the comments it seems that this particular solution does not work well (or at all) on Windows 7. The following thread talks about this

Tuesday, June 1, 2021
 
shin
answered 7 Months ago
17

Edit: As Charles Bailey rightly points out in a comment below, this won't work if there are characters buffered in stdin, and there's really no good way to work around that. If you're running with a debugger attached, John Dibling's suggested solution is probably the cleanest solution to your problem.

That said, I'll leave this here and maybe someone else will find it useful. I've used it a lot as a quick hack of sorts when writing tests during development.


At the end of your main function, you can call std::getchar();

This will get a single character from stdin, thus giving you the "press any key to continue" sort of behavior (if you actually want a "press any key" message, you'll have to print one yourself).

You need to #include <cstdio> for getchar.

Tuesday, June 1, 2021
 
macha
answered 7 Months ago
28

Since you use the main() method - do you need it to be in the same process? If not, you may try to create it as a new Process (java.lang.Process).

The Process class provides the necessary methods to capture StdOut, StdErr and/or StdIn.

Note Since everything runs in it's own process, there should be no issues with thread-safety. However you will still have to find the location, the .class file (or at least the root) is located in, so that you can run/create the Process with java here.goes.your.ClassName.

Friday, August 6, 2021
 
ProfK
answered 4 Months ago
22

If you want to be able to add and remove CustomEvent objects from the event (instead of regular delegates), there are two options:

Make an implicit cast from ICustomEvent to EventHandler (or some other delegate) that returns an instance method of ICustomEvent (probably Invoke), then use the Target property of the delegate to get the original ICustomEvent in the add and remove accessors.

EDIT: Like this:

CustomEvent myEvent;
public event EventHandler MyEvent {
    add {
        if (value == null) throw new ArgumentNullException("value");
        var customHandler = value.Target as ICustomEvent;

        if (customHandler != null)
            myEvent = myEvent.Combine(customHandler);
        else
            myEvent = myEvent.Combine(value);   //An ordinary delegate
    }
    remove {
        //Similar code
    }
}

Note that you'll still need to figure out how to add the first handler if it's a delegate (if the myEvent field is null)


Make a writable property of type CustomEvent, then overload the + and - operators to allow += and -= on the property.

EDIT: To prevent your callers from overwriting the event, you could expose the previous value in CustomEvent (I'm assuming it works like an immutable stack) and, in the setter, add

if (myEvent.Previous != value && value.Previous != myEvent)
    throw new ArgumentException("You cannot reset a CustomEvent", "value");

Note that when the last handler is removed, both value and myEvent.Previous will be null.

Friday, August 13, 2021
 
Desmond Hume
answered 4 Months ago
61

The window's shell doesn't support clickable hyperlinks, so no, this isn't possible.

What are you trying to do that warrants the need for hyperlinks in the command shell? Perhaps this application would be better built as a WinForms/WPF or ASP.NET application.

Wednesday, August 25, 2021
 
Xeo
answered 3 Months ago
Xeo
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share