控制台激活关闭事件
問題:服務器上放的控制臺程序很容易被別人或自己誤操作關關閉,那程序正在處理操作的數據可能正處理到一般,這個時候數據庫里面的數據可能只是整個業務的中間狀態,不是我們要的最終結果,咋辦呢??
解決辦法:
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;}#endregionstatic 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);}}
轉載于:https://www.cnblogs.com/liuqiyun/p/9566062.html
總結
- 上一篇: 当我们在谈论multidex65535时
- 下一篇: django之jquery完成ajax