Jako przykład zapewniając UNIX i implementacja okien patrz poniżej. Zauważ, że nadal możesz dołączyć dll Mono.Posix podczas korzystania z Visual Studio.
Dodałem także sygnał SIGTERM, ponieważ jest on uruchamiany przez systemd w systemie UNIX podczas zatrzymywania/restartowania aplikacji jako usługa.
Interfejs narazić zdarzenie wyjściowe realizację
public interface IExitSignal
{
event EventHandler Exit;
}
Unix
realizacji
public class UnixExitSignal : IExitSignal
{
public event EventHandler Exit;
UnixSignal[] signals = new UnixSignal[]{
new UnixSignal(Mono.Unix.Native.Signum.SIGTERM),
new UnixSignal(Mono.Unix.Native.Signum.SIGINT),
new UnixSignal(Mono.Unix.Native.Signum.SIGUSR1)
};
public UnixExitSignal()
{
Task.Factory.StartNew(() =>
{
// blocking call to wait for any kill signal
int index = UnixSignal.WaitAny(signals, -1);
if (Exit != null)
{
Exit(null, EventArgs.Empty);
}
});
}
}
Okna
public class WinExitSignal : IExitSignal
{
public event EventHandler Exit;
[DllImport("Kernel32")]
public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add);
// A delegate type to be used as the handler routine
// for SetConsoleCtrlHandler.
public delegate bool HandlerRoutine(CtrlTypes CtrlType);
// An enumerated type for the control messages
// sent to the handler routine.
public enum CtrlTypes
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT,
CTRL_CLOSE_EVENT,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT
}
/// <summary>
/// Need this as a member variable to avoid it being garbage collected.
/// </summary>
private HandlerRoutine m_hr;
public WinExitSignal()
{
m_hr = new HandlerRoutine(ConsoleCtrlCheck);
SetConsoleCtrlHandler(m_hr, true);
}
/// <summary>
/// Handle the ctrl types
/// </summary>
/// <param name="ctrlType"></param>
/// <returns></returns>
private bool ConsoleCtrlCheck(CtrlTypes ctrlType)
{
switch (ctrlType)
{
case CtrlTypes.CTRL_C_EVENT:
case CtrlTypes.CTRL_BREAK_EVENT:
case CtrlTypes.CTRL_CLOSE_EVENT:
case CtrlTypes.CTRL_LOGOFF_EVENT:
case CtrlTypes.CTRL_SHUTDOWN_EVENT:
if (Exit != null)
{
Exit(this, EventArgs.Empty);
}
break;
default:
break;
}
return true;
}
}
i jak będzie wyglądać invoke dla aplikacji konsoli? Brakuje Ci} od pewnego czasu – Prix
Nie mogę znaleźć Mono.Posix w celu odniesienia się do mojego projektu mógłbyś dać mi dodatkowe wskazówki w tej sprawie ... oba linki są bardzo niekompletne;/ – Prix
@Prix: Mono.Posix .dll jest instalowany przez standardowy instalator Mono 2.10.2, z jakiej dystrybucji korzystasz? Ponadto dla aplikacji konsolowej można pominąć 'Application.Invoke' i po prostu wywołać logikę czyszczenia z wątku sygnału. – skolima