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