Windows服务OnStop()未调用

我用C#编写了一个程序,作为Windows服务运行。 应用程序启动并运行正常,但是当我使用pipe理控制台停止服务时,OnStop函数不会被调用。

OnStart方法为主程序启动后台线程,后台线程启动另一个线程和一个ThreadPool来为其工作。

OnStop我设置一个布尔标志,所有其他线程检查,看看他们是否应该停止处理。 线程应该完成,程序应该结束。

这是我的OnStart的代码

protected override void OnStart(string[] args) { base.OnStart(args); mainProgram.IsBackground = true; mainProgram.Start(); } 

该代码有效。 下面是OnStop的代码,据我所知可以不被调用。

 protected override void OnStop() { Log.LogMessage("Caught shutdown signal from the OS", "debug"); base.OnStop(); shutdown = true; mainProgram.Join(15000); if (mainProgram.IsAlive) mainProgram.Abort(); } 

该日志消息永远不会写入日志文件。

任何帮助,将不胜感激。 我甚至不知道从哪里开始寻找。 谢谢。

编辑我解决了locking后台线程的问题。 我也注意到了日志声明,所以我知道日志声明不会引起问题。

除了布尔标志之外,我还添加了一个ManualResetEvent。 OnStop现在看起来像这样:

 protected override void OnStop() { System.Diagnostics.Debugger.Break(); //Log.LogMessage("Caught shutdown signal from the OS", "debug"); base.OnStop(); shutdown = true; ShutdownX.Set(); //this is the ManualResetEvent mainProgram.Join(15000); if (mainProgram.IsAlive) mainProgram.Abort(); } 

这个应该停止代码的地方是在mainProgram.RunAgent()函数(这是它自己的线程)while(!shutdown){

  SqlCommand DbCommand = dbConnection.CreateCommand(); DbCommand.CommandText = "SELECT id, SourceID, CastingSN, Result FROM db_owner.queue"; SqlDataReader DbReader = null; try { DbReader = DbCommand.ExecuteReader(); while (DbReader.Read() && !shutdown) { long SourceID = DbReader.GetInt64(1); string CastingSN = DbReader.GetString(2); bool Result = DbReader.GetBoolean(3); WaitCallback callback = new WaitCallback(oComm.RunAgent); CommunicatorState commstate = new CommunicatorState(CastingSN, Result, SourceID); ThreadPool.QueueUserWorkItem(callback, commstate); callback = null; commstate = null; } //Console.WriteLine("Finished Queueing Threads"); } catch (SqlException Ex) { Log.LogMessage("There was an error with a query run on the FlexNet Database.", "error"); Log.LogMessage(">> " + Ex.Message, "error"); } finally { if (DbReader != null) DbReader.Dispose(); DbCommand.Dispose(); } ManualResetEvent[] handles = new ManualResetEvent[2] { eventX, ShutdownX }; WaitHandle.WaitAny(handles); //eventX.WaitOne(Timeout.Infinite, true); } 

认为这应该从数据库中读取,排队它find的所有线程,然后等待所有线程完成处理(eventX重置事件)或ShutdownX事件。

一旦ShutdownX事件被触发,外部循环不应该继续,因为closures布尔是真的,然后线程closures它的SQL连接,应该终止。 没有发生这种情况。 有任何想法吗?

您正在使用ThreadPool 。 据报道, 直到线程池中的所有任务完成, OnStop被调用。 另见这里和这里 。 但是,我认为这不是主要或唯一的原因,因为有些人似乎正在成功地使用它 。

在我看来,你的问题目前说, OnStop永远不会被调用,但你已经看到它发出的日志消息。 所以我认为, OnStop确实被调用,但是一些线程并没有注意到这一点。

请使用单个全局对象将所有获取或设置shutdown代码封装在lock语句中。 这不是为了原子性或相互排斥。 这是为了确保多处理器系统上正确的内存限制。