J E*_*lis 40 c# windows-services
我继承了用C#编写的Windows服务.在极少数情况下,它会严重失败.但是,如何彻底失败并不清楚.Ross Bennett在bytes.com上优雅地陈述了这个问题.为了简单起见,我将在这里引用他.
啊,伙计们!
我一直在寻找这个,但我似乎无法从MSDN或谷歌中删除任何文档.我已经回顾了我在MSDN中开发Windows服务的每篇.NET文章.
我正在开发一个Windows服务应用程序.此服务从其他"管理器"应用程序存放的系统注册表(HKLM)中读取其配置数据.没有问题.
该服务使用工作线程来完成其工作.线程在OnStart()中创建,并在OnStop()中发信号/加入/处置.再次,没有问题.
在以下情况下,一切都很美妙:
- 系统管理员已正确设置所有内容,并且
- 外部网络资源都可以访问.
但当然,我们作为开发人员根本不能依赖:
- 系统管理员已正确设置所有内容,或
- 可以访问外部网络资源.
真的,我们需要的是服务应用程序有一些自己死亡的方式.如果网络资源出现故障,我们需要停止服务.但更重要的是,我们需要SCM知道它已经自行停止了.SCM需要知道该服务已经"失败"......并且还没有被某人关闭.
在"OnStart()"方法中调用"return"或抛出异常对于仍处于启动过程中的服务甚至没有帮助.SCM快速启动并且进程在任务管理器中继续运行 - 尽管它是实际上并没有做任何事情,因为从未创建和启动工作线程.
使用ServiceController实例也不会这样做.这似乎是SCM正常关机 - 而不是服务故障.因此,没有任何恢复操作或重启发生.(另外,MSDNful文档警告有关使用ServiceController使ServiceBtroller自身发生的ServiceBase后代的危险.)
我读过人们在PInvoking调用本机代码时只是为了在SCM中设置"Stopped"状态标志而搞乱的文章.但这并不会关闭服务运行的过程.
我真的很想知道以下方面:
- 从服务中关闭服务,在哪里
- SCM被适当地通知服务已经"停止",并且
- 该过程从任务管理器中消失.
涉及ServiceControllers的解决方案似乎不合适,只是因为2不满意.(框架文件特别禁止这样做,顺便提一下.)
我很欣赏任何建议,指向文档,甚至是有充分理由的推测.:-)哦!而且我很高兴能够接受我的错失.
最亲切的,
罗斯贝内特
Ste*_*end 33
本机代码中的最佳实践是使用非零退出代码调用SetServiceStatus以指示1)它已停止并且2)出错.
在托管代码中,您可以通过ServiceBase.ServiceHandle属性和P/Invoke-Win32 API 获取SCM句柄来实现相同的效果.
我不明白为什么SCM会对此进行不同的处理,而不是将ServiceBase.ExitCode属性设置为非零,然后ServiceBase.Stop实际调用.如果服务处于恐慌模式,P/Invoke可能更直接.
我发现Environment.Exit(1)对我来说很好.我通常把它放在一个捕获未处理的异常的方法中,并在我停止之前记录问题.它完全破坏了服务,但SCM也知道它已关闭.您可以将SCM设置为在服务次数下降x次时自动重新启动服务.我发现这比编写自己的重启/关闭代码更有用.