c# - 优雅地处理 Windows 服务的关闭

标签 c# multithreading windows-services

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

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

由于上述问题,我的问题如下:您将如何实现一种故障安全的方式来处理 Windows 服务的关闭?我有一个 volatile bool 值作为关闭信号,由我的服务基类中的 OnStop() 启用,并且应该优雅地停止我的主循环,但如果其他层中有一个操作正在执行,那将毫无值(value)是时候执行该操作了。

应该如何处理?我目前不知所措,需要一些创意输入。

最佳答案

我会使用 CancellationTokenSource 并将取消 token 从 OnStop 方法向下传播到所有层,所有线程和任务都从那里开始。它在框架中,所以如果您关心它,它不会破坏您的松散耦合(我的意思是,无论您在哪里使用线程/任务,您都可以使用“CancellationToken”。

这意味着您需要调整异步方法以将取消标记考虑在内。

您还应该知道 ServiceBase.RequestAdditionalTime .如果无法及时取消所有任务,您可以申请延期。

或者,也许您可​​以探索 IsBackground选择。当进程即将退出时,您的 Windows 服务中启用此功能的所有线程都会被 CLR 停止:

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.

关于c# - 优雅地处理 Windows 服务的关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25178553/

相关文章:

c# - 使用在端点 : correct UPN does not work 上设置身份的 WCF

c# - 如何将控制台应用程序转换为 Windows 服务?

c# - UnityWebRequest如何打印所有Request headers

c# - 为什么在存在 MEF 时使用 ServiceLocator?

Android 单选按钮有时不会被选中

perl - 如何在 FreeBSD 7.1 下编译具有线程支持的 Perl 5.10?

c# - 使用 InstallUtil 安装带有启动参数的 Windows 服务

c# - c#中的Get和Set方法到底是如何使用和实现的

c# - 使用 Nhibernate 检查已用 key 的最佳方法?

python - 使用 Python 和 C api 的多线程