控制台激活关闭事件
问题:服务器上放的控制台程序很容易被别人或自己误操作关关闭,那程序正在处理操作的数据可能正处理到一般,这个时候数据库里面的数据可能只是整个业务的中间状态,不是我们要的最终结果,咋办呢??
解决办法:
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); } }