3

我有一个具有自定义配置部分的 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 服务中,当它试图启动时会发生这种情况,而且它真的很难看(它提供启动调试器)。我怎样才能优雅地处理这个错误?我尝试将 OnStart 方法包装在 try/catch 中,但没有效果。

谢谢。

4

3 回答 3

2

Or better yet (as you might need multiple such a properties), using the code from @Ricardo Villiamil, create:

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

Then use it from any property you need to.

EDIT: actually, after re-reading the question once more, looks like this solves your problem only half-way, as if the value is out of the defined range, it will throw exception anyway.

EDIT2: You can hook the AppDomain.UnhandledException event in the static ctor of your config section handler. The static ctor is ran before any instance or static member of a class are accessed, so it guarantees that you will intercept the exception even if the main method of your service is not yet called.

And then, when you intercept and log the error, you can exit the service with some error code != 0 ( Environment.Exit(errorCode) ), so the service manager knows it failed, but not try to invoke a debugger.

于 2009-01-23T20:36:11.633 回答
0

Ok I think I have it. In my service I have code that looks like this in the constructor:

config = ConfigurationManager.GetSection("MyCustomConfigSection") as MyCustomConfigSectionHandler;

This is where the error is thrown. I can catch the error and log it. The error must be rethrown in order to prevent the service from continuing. This still causes the ugly behavior but at least I can log the error thereby informing the user of why the service did not start

于 2009-01-23T22:05:25.667 回答
-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;
于 2009-01-23T19:22:31.627 回答