zoukankan      html  css  js  c++  java
  • 控制台激活关闭事件

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

    解决办法:

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

      

  • 相关阅读:
    关联A850刷机包 高级电源 时间中心 优化 ROOT 动力 美化 简化
    CodeForces 425E Sereja and Sets
    int有符号和无符号类型内存 -- C
    软件体系结构————防御性编程
    Hibernate各保存方法之间的差 (save,persist,update,saveOrUpdte,merge,flush,lock)等一下
    椭圆识别
    UVa 10223
    照片详细解释YUV420数据格式
    LeetCode:Reverse Integer
    看了此文你还不懂傅里叶变换,那就来掐我吧
  • 原文地址:https://www.cnblogs.com/liuqiyun/p/9566062.html
Copyright © 2011-2022 走看看