首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >检测控制台应用程序何时关闭/终止?

检测控制台应用程序何时关闭/终止?
EN

Stack Overflow用户
提问于 2011-07-01 18:04:47
回答 2查看 11.6K关注 0票数 21

我想让我的控制台应用程序安全退出,该应用程序将使用mono在linux上运行,但我找不到一个解决方案来检测是否向它发送了信号或用户是否按下了ctrl+c。

在windows上有一个内核函数SetConsoleCtrlHandler,它可以完成这项工作,但它不能在mono上工作。

如何在控制台应用程序上获取关闭事件以安全退出它?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-07-01 18:22:41

你需要使用Mono.UnixSignal,Jonathan Pryor发布了一个很好的示例:http://www.jprl.com/Blog/archive/development/mono/2008/Feb-08.html

Mono页面上还有一个较短的示例:FAQ / Technical / Operating System Questions / Signal Handling

代码语言:javascript
复制
// Catch SIGINT and SIGUSR1
UnixSignal[] signals = new UnixSignal [] {
    new UnixSignal (Mono.Unix.Native.Signum.SIGINT),
    new UnixSignal (Mono.Unix.Native.Signum.SIGUSR1),
};

Thread signal_thread = new Thread (delegate () {
    while (true) {
        // Wait for a signal to be delivered
        int index = UnixSignal.WaitAny (signals, -1);

        Mono.Unix.Native.Signum signal = signals [index].Signum;

        // Notify the main thread that a signal was received,
        // you can use things like:
        //    Application.Invoke () for Gtk#
        //    Control.Invoke on Windows.Forms
        //    Write to a pipe created with UnixPipes for server apps.
        //    Use an AutoResetEvent

        // For example, this works with Gtk#    
        Application.Invoke (delegate () { ReceivedSignal (signal); });
    }});
票数 13
EN

Stack Overflow用户

发布于 2015-09-22 20:24:12

作为提供unix和windows实现的示例,见下文。请注意,在使用Visual Studio时,您仍然可以包含Mono.Posix dll。

我还添加了SIGTERM信号,因为这是由unix中的systemd在停止/重新启动应用程序作为服务时触发的。

接口以公开退出事件。

代码语言:javascript
复制
public interface IExitSignal
{
    event EventHandler Exit;
}

Unix实现

代码语言:javascript
复制
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);
            }

        });
    }

}

Windows实现

代码语言:javascript
复制
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;
    }


}
票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6546509

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档