|
|
1
18
一旦您的
有几种方法可以让您的服务退出。
首先,你可以修改
其次,将线程标记为 background 螺纹(参见 here 了解更多详细信息)。听起来您正在为线程使用System.Threading.Thread类,默认情况下,这些线程是前台线程。这样做将确保线程不会阻止进程退出。如果只执行托管代码,这将很好地工作。如果有一个线程正在等待非托管代码,我不确定设置isbackground属性是否仍会导致该线程在关闭时自动退出,也就是说,您可能仍然需要重新编写线程模型,使该线程响应关闭请求。 |
|
|
2
11
当您从onstop返回时,服务控制管理器(SCM)将返回。因此,您需要修复onstop实现来阻塞,直到所有线程都完成。 一般的方法是让onstop向所有线程发出停止信号,然后等待它们停止。为了避免无限期阻塞,可以给线程一个停止的时间限制,然后在线程花费太长时间时中止它们。 以下是我过去所做的:
注意在4中,在正常情况下,您应该给线程足够的时间退出。只有在线程挂起的异常情况下才应中止…在这种情况下,中止并不比用户或系统终止进程(如果计算机正在关闭,则终止进程)更糟糕。 |
|
3
1
这样做的简单方法如下:
ManualResetEvent shutdownEvent; -在服务启动时,创建手动重置事件并将其设置为未签名的初始状态 shutdownEvent = new ManualResetEvent(false); -在服务停止事件时 shutdownEvent.Set(); 不要忘记等待线程结束 do
{
//send message for Service Manager to get more time
//control how long you wait for threads stop
}
while ( not_all_threads_stopped );
-每个线程必须不时地测试要停止的事件 if ( shutdownEvent.WaitOne(delay, true) ) break; |
|
|
4
0
发出线程循环退出的信号,进行清理并执行线程连接-S。在出现问题的地方,查看作为测量/秒表需要多长时间。避免因各种原因导致的停机失败。 |
|
5
0
要回答第一个问题(为什么服务会继续运行30秒以上): 原因很多。例如,在使用wcf时,停止主机会导致进程停止接受传入请求,并在停止前等待处理所有当前请求。 其他类型的网络操作也同样如此:操作将尝试在终止之前完成。这就是为什么大多数网络请求在请求可能“挂起”(服务器故障、网络问题等)时具有内置超时值的原因。 如果没有更多关于你到底在做什么的信息,就没有办法确切地告诉你为什么要花30秒,但这可能是一个超时。 要回答第二个问题(为什么服务控制器返回):我不确定。我知道ServiceController类有一个WaitForState方法,它允许您等待直到达到给定的状态。服务控制器可能正在等待预定的时间(另一个超时),然后强制终止应用程序。 也很可能调用了base.onstop方法,并且onstop方法已返回,向ServiceController发出进程已停止的信号,而实际上有一些线程尚未停止。您负责终止这些线程。 |
|
|
6
0
对于看起来像我这样的人,如果想要缩短关闭时间的解决方案,请尝试设置服务主机的closeTimeout。 现在我试图理解为什么没有它要花那么多时间才能停下来,我也认为这是线程问题。我确实在Visual Studio中查找了附加到服务并停止了它:我的服务启动了一些仍在运行的线程。 现在的问题是:真的是这些线程让我的服务停止得这么慢吗?微软没有考虑过吗?你不认为这可能是端口释放问题或其他问题吗?因为处理线程s to是浪费时间的,最终没有更短的关闭时间。 |
|
|
7
0
马特·戴维斯很完美。
此外,如果您的任何任务正在执行更长的操作(如存储过程调用),因此连接超时需要更长一点,那么您实际上可以请求SCM更多时间关闭。见: https://msdn.microsoft.com/en-us/library/system.serviceprocess.servicebase.requestadditionaltime(v=vs.110).aspx 这对于避免可怕的“标记删除”状态很有用。最大值是在注册表中设置的,所以我通常请求线程通常关闭的最大预期时间(并且不会超过12秒)。参见: what is the maximum time windows service wait to process stop request and how to request for additional time 我的代码看起来像:
|