【发布时间】:2010-12-04 10:24:34
【问题描述】:
我有一个用 C# 编写的 Windows 服务,它创建大量线程并建立许多网络连接(WMI、SNMP、简单 TCP、http)。尝试使用 Services MSC 管理单元停止 Windows 服务时,停止服务的调用返回相对较快,但该进程继续运行大约 30 秒左右。
主要问题是停止需要 30 多秒的原因可能是什么。我可以寻找什么以及如何寻找它?
第二个问题是为什么即使进程仍在运行,服务 msc 管理单元(服务控制器)仍会返回。有没有办法让它只在进程实际被杀死时才返回?
这是服务的 OnStop 方法中的代码
protected override void OnStop()
{
//doing some tracing
//......
//doing some minor single threaded cleanup here
//......
base.OnStop();
//doing some tracing here
}
编辑以响应线程清理答案
你们中的许多人回答说我应该跟踪我的所有线程然后清理它们。我不认为这是一种实用的方法。首先,我无法访问一个位置的所有托管线程。该软件非常大,包含不同的组件、项目,甚至可以创建线程的 3rd 方 dll。我无法在一个位置跟踪所有这些,或者有一个所有线程都检查的标志(即使我可以让所有线程检查一个标志,许多线程也会阻塞信号量之类的东西。当它们阻塞时,它们可以'不检查。我将不得不让他们等待超时,然后检查这个全局标志并再次等待)。
IsBackround 标志是一个有趣的检查。尽管如此,我怎样才能知道我是否有任何前台线程在运行?我将不得不检查创建线程的代码的每个部分。有没有其他方法,也许有一个工具可以帮助我找到这个。
但最终,该过程确实停止了。似乎我只需要等待一些东西。但是,如果我在 OnStop 方法中等待 X 时间,则该过程大约需要 30 秒 + X 才能停止。无论我尝试做什么,在 OnStop 返回后,该过程似乎需要大约 30 秒(并不总是 30 秒,它可能会有所不同)才能真正停止。
【问题讨论】:
-
你有没有放任何东西让其他线程适当地停止?它们是后台线程还是前台线程?
-
如果您使用可以在内部创建线程的组件,理想情况下,它们各自都会公开一个您可以在 OnStop 中调用的适当关闭机制,因此您不必直接管理它们的线程。如果没有,或者如果您不想打扰干净退出并且只想让进程立即终止,请尝试调用 Environment.Exit... 但是我不确定当服务终止时 SCM 将如何反应向它发送停止命令。
标签: .net windows-services process terminate