我有一个具有自定义配置部分的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方法,但它没有效果。
感谢。
答案 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;