权威code表示prevents C#控制台应用程序从退出[直到定制清理code已完成] [英] The definitive code that prevents a c# console app from exiting [until custom cleanup code has completed]

查看:189
本文介绍了权威code表示prevents C#控制台应用程序从退出[直到定制清理code已完成]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们能共同努力,拿出一些作品进行控制-C,控制通断,注销,窗口X按钮pressed等?

Can we work together to come up with something that works for control-c, control-break, log off, window X button pressed, etc?

下面是我到目前为止有:

Here is what I have so far:

class Program
{  
    private static ConsoleEventHandlerDelegate consoleHandler;
    delegate bool ConsoleEventHandlerDelegate(CtrlTypes eventCode);

    static void Main(string[] args)
    {
        consoleHandler = new ConsoleEventHandlerDelegate(ConsoleCtrlCheck);
        SetConsoleCtrlHandler(consoleHandler, true);

        System.Diagnostics.Process.GetCurrentProcess().Exited 
           += delegate(object sender, EventArgs e) 
        {              
            GeneralManager.Stop();
        };

        Console.CancelKeyPress += delegate(object sender,
                                ConsoleCancelEventArgs e)
        {
            e.Cancel = false;
            GeneralManager.Stop();
        };

        GeneralManager.Start();
    }

    private static bool ConsoleCtrlCheck(CtrlTypes ctrlType)
    {
        switch (ctrlType)
        {                
            case CtrlTypes.CTRL_C_EVENT:

                Console.WriteLine("CTRL+C received!");
                GeneralManager.Stop();
                break;

            case CtrlTypes.CTRL_BREAK_EVENT:
                isclosing = true;
                Console.WriteLine("CTRL+BREAK received!");
                GeneralManager.Stop();
                break;

            case CtrlTypes.CTRL_CLOSE_EVENT:

                Console.WriteLine("Program being closed!");
                GeneralManager.Stop();
                break;

            case CtrlTypes.CTRL_LOGOFF_EVENT:
            case CtrlTypes.CTRL_SHUTDOWN_EVENT:

                Console.WriteLine("User is logging off!");
                GeneralManager.Stop();
                break;                           
        }
        return true;
    }

    #region unmanaged

            [DllImport("kernel32.dll")]
          static extern bool SetConsoleCtrlHandler(ConsoleEventHandlerDelegate
            handlerProc, bool add);

    public delegate bool HandlerRoutine(CtrlTypes CtrlType);

    public enum CtrlTypes
    {
        CTRL_C_EVENT = 0,
        CTRL_BREAK_EVENT,
        CTRL_CLOSE_EVENT,
        CTRL_LOGOFF_EVENT = 5,
        CTRL_SHUTDOWN_EVENT
    }

    #endregion
}

两个问题:

  1. 在管理控制,中断处理程序,如果我们设置 e.Cancel = TRUE 失败与例外.NET4。这说明,没有变通的MSDN文章中:的http://msdn.microsoft.com/en-us/library/system.consolecanceleventargs.cancel.aspx

  1. In the Managed Control-Break handler, if we set e.Cancel = true it fails with an exception for .Net4. This is noted in the MSDN article with no work-around: http://msdn.microsoft.com/en-us/library/system.consolecanceleventargs.cancel.aspx

我不知道该怎么取消关闭在 ConsoleCtrlCheck 。我得到一两秒钟做一些清理工作,但我宁愿取消,并确保这一切得到正确完成。

I don't know how to cancel the close in the ConsoleCtrlCheck. I get a second or two to do some cleanup, but I'd rather cancel and make sure it all gets done properly.

更新:

感谢您的答复。这两个Upvoted。将等待看看是否有人能拿出一个答复直接解决了我的要求,否则将接受的使用NT服务的答案之一。

Thanks for the replies. Upvoted both. Will wait to see if anyone can come up with a reply that directly solves what I asked for, otherwise will accept one of the "use NT services" answers.

推荐答案

我还没有尝试做这种事情有一个控制台应用程序,但你可以做的更好了Windows窗体(或WCF应用程序)。他们会给你一个 的FormClosing 事件是撤销。另外,使用Windows服务,如果你正在编写一个网络服务,它提供了一个接口,干净的停止您的应用程序。

I have not tried to do this kind of thing with a console app, but you may do better with a Windows Forms (or WCF app). They will give you a FormClosing event which is cancellable. Alternately, use a Windows Service if you are writing a network service, it provides an interface to cleanly stop your application.

如果你真的热衷于一个控制台应用程序,也许是尝试{}终于{} 周围所有的code或一些更奇特的像<一个条款HREF =htt​​p://msdn.microsoft.com/en-us/library/fh21e17c.aspx相对=nofollow>关键finaliser 可以允许您运行清理code。但是,这确实是不正确的工具来完成工作。

If you are really keen on a console app, perhaps a try {} finally {} clause around all your code or something more exotic like a critical finaliser may allow you to run clean up code. But this is really not the right tool for the job.

和有你不能prevent你的应用程序被关闭,如例:电源故障或任务管理器kill命令(如果一个应用程序没有关闭通过X,任务管理器是一个工具我ð端起)。

And there are cases which you cannot prevent you app being closed, eg: power failure, or Task Manager kill command (and if an app didn't close via the X, Task Manager is the first tool I'd reach for).

所以,$ C C服务应用程序$这样,所有的客户端请求被记录到一个事务日志(如SQL服务器一样)。如果您意外(通过任何情况下)任何已发生了中断,直到这一点是在日志中。当你的服务下次启动,回放日志。

So, code your service application such that all client requests are logged to a transaction log (like SQL server does). If you are unexpectedly interrupted (by whatever circumstance) anything which has happened up until that point is in the log. When your service next starts, replay that log.

你的一个东西日志将被我是完全关闭的时间 T 。如果重新启动,并没有发现你的日志的结尾该项目,你知道的东西出了问题,你可以采取任何的行动是必需的。

One of your things to log will be "I was shutdown cleanly at time T". If you restart and don't find that item at the end of your log, you know something went wrong, and you can take whatever action is required.

如果你需要知道你的服务是干什么的,使用许多记录的框架来管事件到第二个应用程序,它只是显示的活动。

If you need to know what your service is doing, use one of the many logging frameworks to pipe events to a second app, which just displays activity.

这篇关于权威code表示prevents C#控制台应用程序从退出[直到定制清理code已完成]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆