当前位置:  开发笔记 > 编程语言 > 正文

捕获控制台出口C#

如何解决《捕获控制台出口C#》经验,为你挑选了3个好方法。

我有一个包含很多线程的控制台应用程序.有些线程可以监视某些条件,如果它们是真的则终止程序.这种终止可以随时发生.

我需要一个可以在程序关闭时触发的事件,以便我可以清理所有其他线程并正确关闭所有文件句柄和连接.我不确定.NET框架中是否已经内置了一个,所以我在编写自己的框架之前就已经问过了.

我想知道是否有一个事件:

MyConsoleProgram.OnExit += CleanupBeforeExit;

flq.. 92

我不确定我在网上找到代码的位置,但我现在在我的一个旧项目中找到了它.这将允许您在控制台中执行清理代码,例如,当它突然关闭或由于关闭时...

[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);
  ...
}

更新

对于那些没有检查评论的人来说,似乎这个特定的解决方案在Windows 7上运行不佳(或根本没有).以下主题讨论了这一点



1> flq..:

我不确定我在网上找到代码的位置,但我现在在我的一个旧项目中找到了它.这将允许您在控制台中执行清理代码,例如,当它突然关闭或由于关闭时...

[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);
  ...
}

更新

对于那些没有检查评论的人来说,似乎这个特定的解决方案在Windows 7上运行不佳(或根本没有).以下主题讨论了这一点


这在Windows 7(64位)上对我很有用.不知道为什么每个人都说不.我做的唯一主要修改是摆脱enum和switch语句,并从方法中"返回false" - 我在方法体中做了我所有的清理工作.
这很好用,只有`bool Handler()`必须`返回false;`(它在代码中什么都不返回)所以它会起作用.如果返回true,则Windows会提示"立即终止处理"对话框.= d
你能用它取消退出吗?除了当它关闭时!
看起来此解决方案不适用于Windows 7 for shutdown事件,请参阅http://social.msdn.microsoft.com/Forums/en/windowscompatibility/thread/abf09824-4e4c-4f2c-ae1e-5981f06c9c6e
请注意,如果在"Handler"方法中放置断点,则会抛出NullReferenceException.检查VS2010,Windows 7.
请参阅http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/545f1768-8038-4f7a-9177-060913d6872f/和http://www.pinvoke.net/default.aspx/kernel32. CreateToolHelp32Snapshot函数

2> JJ_Coder4Hir..:

完整的工作示例,使用ctrl-c,用X关闭窗口并杀死:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

namespace TestTrapCtrlC {
    public class Program {
        static bool exitSystem = false;

        #region Trap application termination
        [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) {
            Console.WriteLine("Exiting system due to external CTRL-C, or process kill, or shutdown");

            //do your cleanup here
            Thread.Sleep(5000); //simulate some cleanup delay

            Console.WriteLine("Cleanup complete");

            //allow main to run off
            exitSystem = true;

            //shutdown right away so there are no lingering threads
            Environment.Exit(-1);

            return true;
        }
        #endregion

        static void Main(string[] args) {
            // Some boilerplate to react to close window event, CTRL-C, kill, etc
            _handler += new EventHandler(Handler);
            SetConsoleCtrlHandler(_handler, true);

            //start your multi threaded program here
            Program p = new Program();
            p.Start();

            //hold the console so it doesn’t run off the end
            while (!exitSystem) {
                Thread.Sleep(500);
            }
        }

        public void Start() {
            // start a thread and start doing some processing
            Console.WriteLine("Thread started, processing..");
        }
    }
}



3> jmservera..:

检查还:

AppDomain.CurrentDomain.ProcessExit


这只会出现从return或Environment.Exit中捕获退出,它不会捕获CTRL + C,CTRL + Break,也不会捕获控制台上的实际关闭按钮.
推荐阅读
Life一切安好
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有