【问题标题】:Shutting down a windows service that has threads关闭具有线程的 Windows 服务
【发布时间】:2010-05-08 17:07:42
【问题描述】:

我有一个用 .NET 3.5 (c#) 编写的 Windows 服务,它带有一个在每个回调中生成多个线程的 System.Threading.Timer。这些只是普通线程(没有线程池),我已经在每个线程上设置了IsBackground = true,因为我只会运行托管代码。

当用户停止服务时,所有线程会发生什么?他们会优雅地死去吗?我没有任何通过调用加入或中止来管理线程的代码。假设IsBackground = true 足以假设当用户停止服务时线程将被释放和停止是否正确?当有人通过 Service Manager GUI 停止 Windows 服务时,究竟会发生什么?它会在触发 OnStop 事件后终止进程吗?

这对我来说实际上是可以接受的,因为我建立了一个单独的机制,允许用户在停止服务之前确定没有线程。这是通过从在 Windows 服务内运行的 ServiceHost 公开的 2 个 WCF 方法完成的。有一种方法可以停止生成新线程,另一种方法可以查询还有多少正在运行的线程。

我只是好奇如果他们跳过这些步骤并停止服务会发生什么......似乎 IsBackground 有助于实现这一点:

【问题讨论】:

    标签: wcf windows-services multithreading isbackground


    【解决方案1】:

    来自您提供的 MSDN 链接:

    线程要么是后台线程,要么是前台线程。后台线程与前台线程相同,只是后台线程不会阻止进程终止。一旦属于一个进程的所有前台线程都已终止,公共语言运行时就会结束该进程。 所有剩余的后台线程都已停止且未完成。

    将线程的IsBackground 属性设置为true 将允许您的Windows 服务在OnStop() 回调完成执行并且所有前台线程(如果有)都退出后立即终止。后台线程将在它们碰巧处于执行状态时停止,因此如果这些线程需要正常终止,您将需要使用不同的机制。

    一种方法是使用前台线程来检查ManualResetEvent 对象,该对象指示线程关闭。在您的OnStop() 回调中,设置 ManualResetEvent,然后使用Join() 等待线程退出。如果它们没有在合理的时间内退出,您可以强制终止它们,因为进程正在退出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-02
      • 1970-01-01
      • 1970-01-01
      • 2021-02-20
      • 1970-01-01
      • 2012-12-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多