【问题标题】:how to close all background threads of a Windows Service application ?如何关闭 Windows 服务应用程序的所有后台线程?
【发布时间】:2013-06-20 13:33:25
【问题描述】:

我创建了一个 Windows 服务应用程序,我打开了大约 10000 个线程,我想关闭所有线程,就像我关闭 winform 应用程序时所有后台线程都关闭一样,我该如何做到这一点?我不想将所有这些线程的引用存储在一个数组中并使用循环关闭所有线程。

在我使用 Winform 应用程序之前,当我关闭 Winform 应用程序时,所有后台线程都会自行关闭。我想完成类似的事情来关闭 Windows 服务应用程序中的所有线程

任何想法将不胜感激。

【问题讨论】:

  • 如果你只处理停止消息而不做任何其他事情,操作系统应该在大约 20 秒后停止所有线程。
  • 我不清楚你的意思?你的意思是如果我只是过度使用 OnStop 消息并且什么都不做它会停止所有线程吗?还是您的意思是,如果我不覆盖 OnStop 方法,它将关闭所有线程?
  • 在我的覆盖中它只有'base.OnStop();'
  • 我试过了,没有关闭所有线程,你确定调用base.OnStop真的关闭了所有线程吗?
  • 嗨,马丁詹姆斯,请将您的答案发布为答案,我会将其标记为答案,因为这对我有帮助。

标签: c# multithreading windows-services


【解决方案1】:

如果您设置线程属性myThread.isBackground = true,线程将随着所有前台线程被杀死(当您关闭应用程序时)而终止。

但是,创建 10 000 个线程并不是一件好事,因为操作系统将花费更多时间在线程之间切换而不是实际执行线程的代码。在普通计算机上执行这么多线程实际上会比在 2 - 4 核 CPU 上执行 2 - 16 个线程(例如)效率低。

这是一本关于线程的优秀电子书。

PDF:http://www.albahari.info/threading/threading.pdf 网址:http://www.albahari.com/threading/

【讨论】:

  • 如果所有前台线程都被杀死,后台线程也会结束吗?因此,如果应用程序关闭,所有后台线程都将按照 OP 的要求结束,而无需跟踪所有后台线程。
  • 所以如果使用这么多线程不是一个好习惯,你能告诉我应该使用什么方式来创建一个服务于 10000 个客户端的 TCP 服务器
  • 假设整个过程在单台机器上执行,您可以使用允许您对工作项进行排队的线程池。电子书中的所有内容都在我的回答中得到了很好的解释(albahari.com/threading/#_Thread_Pooling)。
【解决方案2】:

我可以看到实现您的目标的两种选择:

  1. 让您的服务应用程序启动另一个负责启动线程的可执行程序。然后让您的服务应用程序在需要时终止该可执行程序。 Executable 程序产生的线程将被杀死,但服务不会。

  2. 在正在运行的线程中设置中断条件。通过设置一个布尔标志,您可以让您的线程退出 while (true) 并退出 Runnable 委托。 (这里我假设你的线程一直在while (true) 中运行,否则你不会问这个问题)。

【讨论】:

  • 毫无疑问,它是一个服务器,所以它必须运行。
  • 我的意思是它们并不是所有的运行状态,即。大多数/全部被某些东西阻止,(大概是网络读取)。
  • @MartinJames 好的,我应该写“活着”而不是“跑步”。它们不能永远被“阻止”,除非实现存在问题。一秒钟或另一秒钟,他们将运行一些代码并最终测试中断条件。
【解决方案3】:

如果您只处理停止消息而不执行任何其他操作,则操作系统应在约 20 秒后停止服务进程中的所有剩余线程。

【讨论】:

  • 为什么要投反对票?我已经对此进行了测试,它有效。如果线程被阻塞,它会起作用。如果线程正在休眠,它会起作用。如果线程正在运行,它就可以工作。
  • OP 的问题基本上可以归结为“我不知道我在做什么。我怎样才能摆脱我所在的洞?” VinceAnity 的正确答案是,“在做之前先了解如何做你正在做的事情。这是一个好的开始。”不幸的是,您的回答相当于:“您不需要知道自己在做什么。操作系统会自动为您清理。”尽管这已成为当今软件开发的普遍观点,但它仍然是一个可怕的观点。
  • @StephenMartin 为什么可怕?假设一个复杂的多线程应用程序在您希望关闭它时处于一般不可预测的状态,您打算如何停止它? a) 设计、开发、编写、测试大量复杂、困难、可能不可靠的线程关闭代码,这些代码在阻塞和运行状态下都难以停止线程。 b) 调用 ExitProcess(0)。在许多应用程序中,使用用户代码“干净地关闭线程”是不现实的。只有操作系统具有在释放正在使用的资源之前停止所有内核上所有状态的所有线程的工具。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-28
  • 1970-01-01
相关资源
最近更新 更多