如何/在Windows服务中处理ConfigurationErrorsException?

时间:2009-01-23 18:57:52

标签: c# windows-services configuration-files

我有一个具有自定义配置部分的Windows服务。在configSectionHandler类中,我使用属性上的属性来验证这样的设置:

    //ProcessingSleepTime Property
    [ConfigurationProperty("ProcessingSleepTime", DefaultValue = 1000, IsRequired = false)]
    [IntegerValidator(MinValue = 5, MaxValue = 60000)]
    public Int32 ProcessingSleepTime
    {
        get
        {
            if (this["ProcessingSleepTime"] == null)
                return 100;

            return (Int32)this["ProcessingSleepTime"];
        }
        set
        {
            this["ProcessingSleepTime"] = value;
        }
    }

如果配置文件中的值验证失败,则抛出ConfigurationErrorsException。在Windows服务中,这种情况发生在尝试启动时,它真的很难看(它提供启动调试器)。我怎样才能优雅地处理这个错误?我尝试在try / catch中包装OnStart方法,但它没有效果。

感谢。

3 个答案:

答案 0 :(得分:1)

或者更好(因为您可能需要多个这样的属性),使用@Ricardo Villiamil的代码,创建:

int GetIntFromConfigSetting(string settingName, int defaultValue)
{
   int retValue = defaultValue;
   if(this.ContainsKey(settingName))
   {
      int sleepInterval;
      if(Int32.TryParse(this[settingName], out sleepInterval)
      {
         retValue = sleepInterval;
      }
   }
   return retValue;
}

然后从您需要的任何属性中使用它。

编辑:实际上,在再次重新阅读问题后,看起来这样只解决了你的问题的一半,就好像价值超出了定义的范围,无论如何它都会抛出异常。

EDIT2:您可以将AppDomain.UnhandledException event挂钩到配置节处理程序的静态ctor中。静态ctor在访问类的任何实例或静态成员之前运行,因此即使尚未调用服务的主方法,也可以保证拦截异常。

然后,当您拦截并记录错误时,您可以使用一些错误代码退出服务!= 0(Environment.Exit(errorCode)),因此服务管理器知道它失败了,但是没有尝试调用调试器

答案 1 :(得分:0)

好的,我想我拥有它。在我的服务中,我在构造函数中看起来像这样:

config = ConfigurationManager.GetSection(“MyCustomConfigSection”)为MyCustomConfigSectionHandler;

这是抛出错误的地方。我可以捕获错误并记录它。必须重新抛出该错误才能阻止服务继续。这仍然会导致丑陋的行为,但至少我可以记录错误,从而通知用户服务没有启动的原因

答案 2 :(得分:-1)

首先,检查您的配置是否包含您要查找的密钥,然后将其包装在try catch中,然后检查它是否是有效的整数:

int retValue = 100;
if(this.ContainsKey("ProcessingSleepTime"))
{
    object sleepTime = this["ProcessingSleepTime"];
    int sleepInterval;
    if(Int32.TryParse(sleepTime.ToString(), out sleepInterval)
    {
       retValue = sleepInterval;
    }
}
return retValue;