C# windows服务立即停止并启动,但不应该
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/558920/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
windows service stops and starts immediately, but it shouldn't
提问by Steven Evers
I'm creating a windows service and after installing the service, it stops and starts immediately, but it shouldn't be at all. Previously, I was getting errors that the service was not responding to the start command in a timely fashion, so I took the init code out and put it in a thread, and now I am here:
我正在创建一个 Windows 服务,安装该服务后,它会立即停止并启动,但根本不应该如此。以前,我收到服务没有及时响应启动命令的错误,所以我把 init 代码拿出来放在一个线程中,现在我在这里:
protected override void OnStart(string[] args)
{
this.EventLog.WriteEntry("ATNotifier Started");
ThreadPool.QueueUserWorkItem(WaitOnEmailsChanged);
ThreadPool.QueueUserWorkItem(Init, "IP");
}
The waitonemailschanged thread simply creates a filesystemwatcher to watch to see if the settings file (xml document) gets changed, and loads in the data from that file if that happens. For the time being, this just waits indefinitely (which is the general case, as that will only be changed a few times a year), as no changes are being made to the xml document.
waitonemailschanged 线程只是创建一个文件系统观察器来观察设置文件(xml 文档)是否被更改,如果发生更改,则从该文件加载数据。目前,这只是无限期地等待(这是一般情况,因为每年只会更改几次),因为没有对 xml 文档进行任何更改。
The Init thread does all kinds of things, including creating and starting a System.Timers.Timer object whose Elapsed method is the meat of the service.
Init 线程执行各种操作,包括创建和启动 System.Timers.Timer 对象,其 Elapsed 方法是服务的核心。
I can't understand why it would start and then immediately stop. I should also note that the eventviewer shows no logs from this app.
我不明白为什么它会开始然后立即停止。我还应该注意到事件查看器没有显示来自这个应用程序的日志。
edit> I tried creating 'proper' threads, with the same results and I've removed everything except the creating and starting of the timer like so:
编辑>我尝试创建“适当的”线程,结果相同,除了创建和启动计时器外,我删除了所有内容,如下所示:
protected override void OnStart(string[] args)
{
this.EventLog.WriteEntry("ATNotifier Started");
m_Timer = new System.Timers.Timer(90000.0); // 1.5 mins
m_Timer.Elapsed += new ElapsedEventHandler(m_Timer_Elapsed);
m_Timer.Start();
}
and I'm still getting the same message. It's almost as if the OnStart is never being called.
我仍然收到相同的消息。就好像 OnStart 从未被调用过一样。
采纳答案by Steven Evers
The problem turned out top be that the EventLog.WriteEntry was throwing an error because there was no EventSource associated with it. see http://msdn.microsoft.com/en-us/library/xzwc042w.aspx
问题原来是 EventLog.WriteEntry 抛出错误,因为没有与之关联的 EventSource。请参阅http://msdn.microsoft.com/en-us/library/xzwc042w.aspx
回答by Alex Reitbort
It might be stopped unexpectedly if your main thread terminates on exception.
如果您的主线程因异常而终止,它可能会意外停止。
回答by Marc Gravell
ThreadPool threads are background threads; they won't keep a process alive. I suspect you need a "proper" thread...
ThreadPool 线程是后台线程;他们不会让进程保持活力。我怀疑你需要一个“适当的”线程......
Try: new Thread(SomeCode).Start();
or similar.
尝试:new Thread(SomeCode).Start();
或类似。
回答by toad
The code you posted doesn't make sense to me. Why set an event handler before creating your Timer?
您发布的代码对我来说没有意义。为什么要在创建 Timer 之前设置事件处理程序?
m_Timer.Elapsed += new ElapsedEventHandler(m_Timer_Elapsed);
m_Timer = new System.Timers.Timer(90000.0); // 1.5 mins
Shouldn't these two lines be swapped?
这两行不应该互换吗?
回答by Fritz H
As far as I can recall, you must actively report to the service manager that the service has successfully started - otherwise, the OnStart method will return, and if the status change has not been reported, the service manager will assume that the service terminated without actually successfully loading itself.
据我所知,你必须主动向服务管理器报告服务已经成功启动——否则,OnStart方法将返回,如果状态改变没有报告,服务管理器将假设服务终止而没有实际上成功加载本身。
Reporting your service as having started successfully is done IIRC by the Service base class, so add the following to the bottom of the OnStart
method:
报告您的服务已成功启动由 Service 基类完成 IIRC,因此将以下内容添加到OnStart
方法的底部:
base.OnStart(args);