c# – 正常处理Windows服务的关闭

假设您有一个多线程 Windows服务,它执行许多不同的操作,这需要花费相当多的时间,例如从不同的数据存储中提取数据,解析所述数据,将其发布到外部服务器等.可以在不同的层中执行操作,例如,应用程序层,存储库层或服务层.

在此Windows服务的生命周期中的某个时刻,您可能希望通过services.msc关闭它或重新启动它,但是如果您无法在服务的时间跨度内停止所有操作并终止Windows服务中的所有线程. msc期望用stop程序完成,它会挂起,你必须从任务管理器中删除它.

由于上面提到的问题,我的问题如下:如何实现处理Windows服务关闭的故障安全方法?我有一个挥发性布尔值作为关闭信号,由我的服务基类中的OnStop()启用,并且应该优雅地停止我的主循环,但如果在某个其他层中有一个操作,这是不值得的是时候做任何操作了.

应如何处理?我目前处于亏损状态,需要一些创造性的投入.

解决方法

我将使用CancellationTokenSource并将取消令牌从OnStop方法传播到所有层,并在那里启动所有线程和任务.它在框架中,所以如果你关心它,它不会破坏你的松散耦合(我的意思是,无论你在哪里使用线程/任务,你也有’CancellationToken’可用.

这意味着您需要调整异步方法以考虑取消令牌.

您还应该知道ServiceBase.RequestAdditionalTime.如果无法在适当的时候取消所有任务,您可以申请延长期.

或者,也许您可​​以探索IsBackground替代方案.当进程即将退出时,CLR会停止Windows服务中启用了此功能的所有线程:

A thread is either a background thread or a foreground thread. Background threads are identical to foreground threads,except that background threads do not prevent a process from terminating. Once all foreground threads belonging to a process have terminated,the common language runtime ends the process. Any remaining background threads are stopped and do not complete.

相关文章

在项目中使用SharpZipLib压缩文件夹的时候,遇到如果目录较深,则压缩包中的文件夹同样比较深的问题。比...
项目需要,几十万张照片需要计算出每个照片的特征值(调用C++编写的DLL)。 业务流程:选择照片...
var array = new byte[4]; var i = Encoding.UTF8.GetBytes(100.ToString("x2"));//...
其实很简单,因为Combox的Item是一个K/V的object,那么就可以把它的items转换成IEnumerable<Dic...
把.net4.6安装包打包进安装程序。 关键脚本如下: 头部引用字符串对比库 !include "WordFunc....
项目需求(Winform)可以批量打印某个模板,经过百度和摸索,使用iTextSharp+ZXing.NetʿreeSp...