启动时C#Windows服务超时 [英] C# Windows Service Timeout on startup

查看:177
本文介绍了启动时C#Windows服务超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在用C#创建的Windows服务中尝试确定超时的原因时遇到困难. 我已经花了很多时间查看有关该问题的几篇文章和主题,但是我不确定还有什么尝试.

I'm having difficulty trying to determine the cause of a timeout in a Windows Service I've created with C#. I've spent a considerable amount of time looking at several posts and topics on the issue but I am unsure what else to try.

出了什么问题?

有时在运行我的Windows服务的某些计算机上,重新启动计算机后它无法成功启动. 我收到有关该服务未能及时启动且在30000毫秒后超时的常见EventLog消息. Windows Server 2003计算机似乎是最常见的模式,但并不总是仅局限于此OS.例如,它可以在其他W2K3机器上正常运行.

Sometimes on certain machines which run my windows service, it does not start successfully after the machine has been rebooted. I receive the common EventLog messages about the Service failing to start in a timely fashion and that it timed out after 30000 milliseconds. Windows Server 2003 machines seem to be the most common pattern but is not always isolated to just this OS. For example it works perfectly fine on other W2K3 machines.

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

The startup failure can be quite random in that sometimes it will start, and other times it will fail so it is very difficult to reproduce the issue on demand. I am also using Log4Net to catch and errors and log them to a RollingFileAppender. However, when the service fails to start, no log file is ever created and no log information saved. It is as if my Service entry thread is blocking and not getting called.

其他详细信息:

  1. Windows服务是用C#编写的,并使用.Net 2.0
  2. 当我的服务没有其他服务依赖项时 已安装.
  3. 该服务exe是一个发布版本,没有签名或验证码 签名.
  4. OnStart方法通过创建一个 线程并启动该线程.不会进行其他初始化 在OnStart中.
  5. 当服务确实无法启动时,请打开服务 列出并手动启动它,每次都可使用该服务 在不到一秒钟的时间内开始.
  1. The Windows service is written in C# and uses .Net 2.0
  2. There are no other service dependencies for my service when installed.
  3. The service exe is a Release build with no signing or authenticode signing.
  4. The OnStart method executes as quickly as possible by creating a Thread and starting that Thread. No other initialization takes place within OnStart.
  5. When the service does actually fail to start, opening the services list and starting it manually works every time and the service starts in probably less than a second.

我在我的Program.cs中添加了以下代码,其中包括该服务的主要入口点. 我挂接到CurrentDomain上的UnhandledException事件,并正在使用log4net记录任何未处理的错误 在ServiceBase周围也有一个try/catch.如果它以某种方式轰炸,请运行,以便我可以记录该错误.

I have the following code added to my Program.cs which include the main entry point for the service. I hook in to an UnhandledException event on the CurrentDomain and am using log4net to log any unhandled errors There's also a try/catch around the ServiceBase.Run in the event it somehow bombs out so that I can log that error.

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);
}

我继承的ServiceBase实现中的代码如下:

The code in my inherited ServiceBase implementation is as follows:

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,其配置详细信息存储在App.config中.

My log4net implementation is using a ConsoleAppender and a RollingFileAppender where its configuration details are stored in the App.config.

在这个阶段,我不确定还有什么尝试. 如果需要更多详细信息,请告诉我.

At this stage I am not sure what else to try. If any more details are needed let me know.

谢谢.

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

Update: Just to update everyone, I'm going to try some of the suggestions such as logging to the EventLog directly or a file instead of Log4Net to see if that's the cause. I Will also try setting the generatePublisherEvidence in the app.config to false. I'm just waiting for an appropriate downtime to access the client's server to test these things out.

推荐答案

我通过关闭配置文件中的发布者证据生成来解决了类似问题.该服务也没有验证码签名,但是添加以下行可立即修复在始终如一地被复制的机器上的问题.

I fixed similar issue by turning off publisher evidence generation in config file. The service also did not have authenticode signing but adding following line immediately fixed the issue on the machine where it has been reproduced consistently.

<runtime>
    <generatePublisherEvidence enabled="false" />
</runtime>

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

Also recommended in this MSDN source:
"We recommend that services use the element to improve startup performance. Using this element can also help avoid delays that can cause a time-out and the cancellation of the service startup. "

这篇关于启动时C#Windows服务超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆