Win服务暂停或停止时,继续任务的最佳方式是什么?

所以我设法写这个服务,现在工作很好。 我想确保在处理数据库logging时,以及由于某种原因,如果服务暂停或closures,应该完成任务,而不是使数据不一致。

我已经尝试了下面的代码,但是我觉得它可能不是正确的,万一它可能不是最好的。 我怎样才能改善上述情况下的代码?

protected override void OnStart(string[] args) { // Update the service state to Start Pending. ServiceStatus serviceStatus = new ServiceStatus(); serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING; serviceStatus.dwWaitHint = 100000; SetServiceStatus(this.ServiceHandle, ref serviceStatus); _eventLog.WriteEntry("RMS Service Started: " + DateTime.UtcNow.ToLongDateString()); CheckDBEntryData(); _timer = new System.Timers.Timer(); _timer.Interval = 60000; _timer.Elapsed += new System.Timers.ElapsedEventHandler(this.SendScheduledSMS); _timer.Start(); // Update the service state to Running. serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING; SetServiceStatus(this.ServiceHandle, ref serviceStatus); } public void SendScheduledSMS(object sender, System.Timers.ElapsedEventArgs e) { if (!_isTaskRunning) { _timer.Enabled = false; _isTaskRunning = true; _eventLog.WriteEntry("RMS Timer Event started: " + DateTime.UtcNow.ToLongDateString()); //TODO: Write the code to check pending RMS and process them _eventLog.WriteEntry("RMS Timer Event stopped: " + DateTime.UtcNow.ToLongDateString()); _isTaskRunning = false; _timer.Enabled = true; } } protected override void OnStop() { CanStop = !_isTaskRunning; // Update the service state to Stop Pending. ServiceStatus serviceStatus = new ServiceStatus(); serviceStatus.dwCurrentState = ServiceState.SERVICE_STOP_PENDING; serviceStatus.dwWaitHint = 100000; SetServiceStatus(this.ServiceHandle, ref serviceStatus); _eventLog.WriteEntry("RMS Service Stopped: " + DateTime.UtcNow.ToLongDateString()); // Update the service state to Stopped. serviceStatus.dwCurrentState = ServiceState.SERVICE_STOPPED; SetServiceStatus(this.ServiceHandle, ref serviceStatus); } 

更多信息

服务正在处理数据库logging并将数据传递给第二个远程服务器,负责向用户发送短信通知。 我需要确保通知只发送一次。 如果我使用事务,并且最后一条logging发生回滚,则下一次处理开始时,它将从头开始发送通知,从而发送重复通知。 所以我不能依靠数据库事务模式,因为我无法控制第二台远程服务器。

该服务可以随时停止。 它可能会崩溃,或者电源可能被中断。 在上述任何情况下,结果应该是一致的。 这就是为什么在与数据库交互时使用事务:当数据库处于一致状态时提交。 如果发生中断(崩溃,SCM停止,掉电,任何事情),数据库将回滚到先前的一致状态。

你完全咆哮错误的树试图修复SCM交互。 你的重点应该围绕数据库工作,确保你的交易界限是正确的。

 serviceStatus.dwCurrentState = ServiceState.SERVICE_STOP_PENDING; serviceStatus.dwWaitHint = 100000; SetServiceStatus(this.ServiceHandle, ref serviceStatus); 

在完成任何现有任务的同时,您需要定期设置服务状态,并等待适当的提示。

“定期”在这里需要一些猜测,但是经常需要足够的时间来确保服务控制管理者不会将服务视为不关闭。 在过去,我每隔几秒就做一次,没有问题。

如果你有任何需要花费很长时间(几十秒)完成的事情,你真的需要重新构造,以便在服务重启时恢复(请记住,关机可能是因为系统即将失去电力或以其他方式需要尽快停止)。