C#Windows服务启动时超时

Apo*_*hen 16 c# windows service log4net timeout

我在使用C#创建的Windows服务中尝试确定超时的原因时遇到了困难.我花了相当多的时间查看有关该问题的几个帖子和主题,但我不确定还有什么可以尝试.

有什么问题?

有时在某些运行我的Windows服务的计算机上,它在重新启动计算机后无法成功启动.我收到有关服务无法及时启动的常见EventLog消息,并且在30000毫秒后超时.Windows Server 2003计算机似乎是最常见的模式,但并不总是与此操作系统隔离.例如,它在其他W2K3机器上运行得非常好.

启动失败可能是相当随机的,因为它有时会启动,有时会失败,因此很难按需重现问题.我也使用Log4Net捕获和错误并将它们记录到RollingFileAppender.但是,当服务无法启动时,不会创建任何日志文件,也不会保存日志信息.就好像我的服务条目线程阻塞而没有被调用.

其他详情:

  1. Windows服务是用C#编写的,使用.Net 2.0
  2. 安装时,我的服务没有其他服务依赖项.
  3. service exe是Release版本,没有签名或authenticode签名.
  4. OnStart方法通过创建Thread并启动该Thread来尽快执行.OnStart中没有其他初始化.
  5. 当服务确实无法启动时,打开服务列表并手动启动它,每次运行时服务可能不到一秒钟.

我在Program.cs中添加了以下代码,其中包括服务的主要入口点.我在CurrentDomain上挂钩到一个UnhandledException事件,并使用log4net记录任何未处理的错误.如果ServiceBase.Run以某种方式炸弹,我还可以记录该错误.

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);
}
Run Code Online (Sandbox Code Playgroud)

我继承的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>
}
Run Code Online (Sandbox Code Playgroud)

我的log4net实现使用ConsoleAppender和RollingFileAppender,其配置详细信息存储在App.config中.

在这个阶段,我不确定还有什么可以尝试的.如果需要更多细节,请告诉我.

谢谢.

更新: 只是为了更新所有人,我将尝试一些建议,例如直接登录EventLog或文件而不是Log4Net,看看是否是原因.我还会尝试将app.config中的generatePublisherEvidence设置为false.我只是在等待适当的停机时间来访问客户端的服务器来测试这些东西.

Dmi*_*try 7

我通过在配置文件中关闭发布者证据生成来修复类似的问题.该服务也没有authenticode签名,但添加以下行立即修复了一致地再现它的机器上的问题.

<runtime>
    <generatePublisherEvidence enabled="false" />
</runtime>
Run Code Online (Sandbox Code Playgroud)

此MSDN源中也建议:
"我们建议服务使用该元素来提高启动性能.使用此元素还可以帮助避免可能导致超时和取消服务启动的延迟."


Chr*_*n.K 2

一般来说,从中产生后台线程OnStart是正确的做法。

为了进行故障排除,您可以尝试通过调用RequestAdditionalTime方法来为您的服务提供更多启动时间OnStart。另外,您可能想要检查是否有任何消息已写入 Windows 事件日志(日志“应用程序”,来源应该是您的服务名称)。