我很难确定在用C#创build的Windows服务中超时的原因。 我花了相当多的时间在这个问题上看几个post和主题,但我不确定还有什么要尝试。
有什么问题?
有时在运行我的Windows服务的某些机器上,在机器重新启动后,它不会成功启动。 我收到有关服务无法及时启动的公共事件日志消息,并在30000毫秒后超时。 Windows Server 2003机器似乎是最常见的模式,但并不总是孤立于这个操作系统。 例如,它在其他W2K3机器上工作得很好。
启动失败可能是非常随机的,因为有时启动失败,有时启动失败,所以很难按需重现问题。 我也使用Log4Net来捕获和错误,并将它们logging到RollingFileAppender。 但是,如果服务启动失败,则不会创build日志文件,也不会保存日志信息。 这就好像我的服务条目线程被阻塞,没有被调用。
其他详情:
我将以下代码添加到我的Program.cs中,其中包括服务的主要入口点。 我挂钩到CurrentDomain上的一个UnhandledException事件,并使用log4netlogging任何未处理的错误还有一个围绕ServiceBase.Run的try / catch事件popup,以便我可以logging该错误。
static void Main() { ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new SchedulerService() }; AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); try { ServiceBase.Run(ServicesToRun); } catch (Exception ex) { Log.Fatal("Unhandled Service Exception", ex); } } private static log4net.ILog _log = null; static log4net.ILog Log { get { if (_log == null) { if (!log4net.LogManager.GetRepository().Configured) { log4net.Config.XmlConfigurator.Configure(); } _log = log4net.LogManager.GetLogger(typeof(Program)); } return _log; } } static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { Exception ex = e.ExceptionObject as Exception; if (ex == null) ex = new Exception(e.ExceptionObject.ToString()); Log.Fatal("Unhandled Service Exception", ex); }
我inheritance的ServiceBase实现中的代码如下所示:
protected override void OnStart(string[] args) { Thread serviceThread = new Thread(new ThreadStart(BackgroundStart)); serviceThread.IsBackground = true; serviceThread.Start(); } private void BackgroundStart() { //Initialize and start worker objects to perform monitoring... //<Snip> }
我的log4net实现使用ConsoleAppender和RollingFileAppender,其configuration细节存储在App.config中。
在这个阶段,我不知道还有什么可以尝试的。 如果有更多的细节需要让我知道。
谢谢。
更新:只是为了更新每个人,我会尝试一些build议,如直接login到EventLog或文件,而不是Log4Net,看看是否是原因。 我也会尝试将app.config中的generatePublisherEvidence设置为false。 我只是在等待适当的停机时间访问客户端的服务器来testing这些事情。
我通过关闭配置文件中的发行者证据生成来解决类似的问题。 该服务也没有authenticode签名,但添加下面的行立即解决了问题一直在复制的机器上。
<runtime> <generatePublisherEvidence enabled="false" /> </runtime>
还在这个MSDN源码中推荐:
“我们建议服务使用元素来提高启动性能,使用这个元素也可以避免延迟,从而导致超时和取消服务启动 。
几件事情要尝试:
将日志消息添加到Main()
的顶部, ServiceBase.Run()
等之前。假设您得到一个日志文件,这些时间戳与Windows事件日志相比如何?
使用“新建项目向导”创建一个全新的服务,并按原样进行部署。 在有问题的机器上,它是否可靠地启动?
获取进程监视器并观察正常启动。 查找任何意外的网络或文件I / O。
确保您的SchedulerService
在构造函数中没有任何工作,并且没有任何静态初始化的依赖关系。
将恢复选项设置为首次失败时重新启动。 这是否可靠地工作?
一般来说,从OnStart
产生一个后台线程是正确的。
出于故障排除的目的,您可以尝试通过从OnStart
调用RequestAdditionalTime方法来为您的服务启动更多的时间。 此外,您可能需要检查是否有任何消息已经写入Windows事件日志(日志“应用程序”,源应该是您的服务名称)。
我也怀疑log4net挂在哪里。 当机器启动时,可能要创建日志的驱动器还没有准备好。 您是否尝试过延迟启动服务?
由于log4net的设计不是一个可靠的日志记录系统,所以我认为将事件日志(以及日志)的未处理异常(特别是对于服务)写入是一个好习惯。