打赏

控制台激活关闭事件

问题:服务器上放的控制台程序很容易被别人或自己误操作关关闭,那程序正在处理操作的数据可能正处理到一般,这个时候数据库里面的数据可能只是整个业务的中间状态,不是我们要的最终结果,咋办呢??

解决办法:

1.主备控制台,切换到备胎程序,检测中间业务状态的数据,加入到处理中(业务状态通常会有点复杂,改起来会比较烦,合适业务状态少,业务简单的场景),即使主机断点,从机依然能处理数据

2.激活关闭窗口事件,暂停循环处理数据的程序,线程打盹3秒,等待将当前数据处理完成,对于断电断网宕机事件就没办法了,这里有个问题,3秒能处理的完吗?有点慌...或者说我10毫秒就处理完了,你让我等3秒那么久。。。

下面是2的例子:

 

class Program
    {
        //实例化Timer类  
        private static System.Timers.Timer aTimer = new System.Timers.Timer();

        #region 激活关闭窗口事件
        public delegate bool ControlCtrlDelegate(int CtrlType);
        [DllImport("kernel32.dll")]
        private static extern bool SetConsoleCtrlHandler(ControlCtrlDelegate HandlerRoutine, bool Add);
        private static ControlCtrlDelegate cancelHandler = new ControlCtrlDelegate(HandlerRoutine);

        /// <summary>
        /// 关闭窗口时的事件
        /// </summary>
        /// <param name="CtrlType"></param>
        /// <returns></returns>
        static bool HandlerRoutine(int CtrlType)
        {

            Console.WriteLine("关闭窗口事件被激活");
            Console.WriteLine("do something...");
            //停止定时扫描
            aTimer.Enabled = false;
            System.Threading.Thread.Sleep(3000);
            Console.WriteLine("可以关闭了");
            //System.Threading.Thread.Sleep(3000);
            return false;
        }

        #endregion
        
        static void Main(string[] args)
        {
            //注册窗口关闭事件
            bool bRet = SetConsoleCtrlHandler(cancelHandler, true);

            aTimer.Elapsed += new ElapsedEventHandler(TaskBegin);
            aTimer.Interval = 1000;
            aTimer.AutoReset = true;//执行一次 false,一直执行true  
                                    //是否执行System.Timers.Timer.Elapsed事件  
            aTimer.Enabled = true;

            #region 防止自动关闭
            var key = string.Empty;
            while (key != "E")
            {
                System.Threading.Thread.Sleep(3000);
                key = Console.ReadLine().ToUpper();
            }
            #endregion

        }

        private static void TaskBegin(object source, System.Timers.ElapsedEventArgs e)
        {
            Console.WriteLine("任务开始执行");
        }
    }

  

 

 

 

 对于2中等待3秒做个优化:

思路:关闭事件中通知数据消费中心终止消费,并循环判断数据消费中心当前消费的那条数据消费结束没,结束了跳出循环,关闭控制台程序

代码应该是下面这个样子:

class Program
    {
        //实例化Timer类  
        private static System.Timers.Timer aTimer = new System.Timers.Timer();

        #region 激活关闭窗口事件
        public delegate bool ControlCtrlDelegate(int CtrlType);
        [DllImport("kernel32.dll")]
        private static extern bool SetConsoleCtrlHandler(ControlCtrlDelegate HandlerRoutine, bool Add);
        private static ControlCtrlDelegate cancelHandler = new ControlCtrlDelegate(HandlerRoutine);

        /// <summary>
        /// 关闭窗口时的事件
        /// </summary>
        /// <param name="CtrlType"></param>
        /// <returns></returns>
        static bool HandlerRoutine(int CtrlType)
        {

            Console.WriteLine("关闭窗口事件被激活");
            Console.WriteLine("do something...");
            //停止定时扫描
            //aTimer.Enabled = false;
            while (Stop!=true)
            {
                Console.WriteLine("当前flag:"+flag);
                System.Threading.Thread.Sleep(1000);
            }
            return false;
        }

        #endregion
        [STAThread]
        static void Main(string[] args)
        {
            //注册窗口关闭事件
            bool bRet = SetConsoleCtrlHandler(cancelHandler, true);

            aTimer.Elapsed += new ElapsedEventHandler(TaskBegin);
            aTimer.Interval = 1000;
            aTimer.AutoReset = true;//执行一次 false,一直执行true  
                                    //是否执行System.Timers.Timer.Elapsed事件  
            aTimer.Enabled = true;

            #region 防止自动关闭
            var key = string.Empty;
            while (key != "E")
            {
                System.Threading.Thread.Sleep(3000);
                key = Console.ReadLine().ToUpper();
            }
            #endregion

        }

        private static int flag = 1;

        private static bool Stop = false;

        private static void TaskBegin(object source, System.Timers.ElapsedEventArgs e)
        {

            Console.WriteLine("任务开始执行");
            Console.WriteLine("线程:"+Thread.CurrentThread.ManagedThreadId);
            flag++;
            if (flag > 20)
            {
                Stop = true;
            }
            Console.WriteLine("flag:"+ flag);
        }
    }

  

posted @ 2018-08-31 15:26  刘奇云  阅读(425)  评论(0编辑  收藏  举报