2009-01-23 15 views
2

J'ai un service Windows qui a une section de configuration personnalisée. Dans la classe configSectionHandler J'utilise des attributs sur les propriétés pour valider les paramètres comme ceci:Comment/Où gérer ConfigurationErrorsException dans un service Windows?

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

Si une valeur dans le fichier de configuration validation échoue, une ConfigurationErrorsException est levée. Dans un service Windows, cela se produit car il essaie de démarrer et c'est vraiment moche (il propose de lancer le débogueur). Comment puis-je gérer avec élégance cette erreur? J'ai essayé d'encapsuler la méthode OnStart dans un try/catch mais cela n'a eu aucun effet.

Merci.

Répondre

1

Ou mieux encore (comme vous pouvez besoin de plusieurs propriétés un tel), en utilisant le code de @Ricardo Villiamil, créez:

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

utiliser ensuite de toute propriété que vous devez. EDIT: en fait, après avoir relu la question une fois de plus, on dirait que cela résout votre problème seulement à mi-chemin, comme si la valeur est hors de la plage définie, elle lancera une exception quand même.

EDIT2: Vous pouvez accrocher le AppDomain.UnhandledException event dans le ctor statique de votre gestionnaire de section de configuration. Le ctor statique est exécuté avant l'accès à une instance ou à un membre statique d'une classe, ce qui garantit que vous intercepterez l'exception même si la méthode principale de votre service n'est pas encore appelée. Et puis, lorsque vous interceptez et notez l'erreur, vous pouvez quitter le service avec un code d'erreur! = 0 (Environment.Exit (errorCode)), le gestionnaire de service sait donc qu'il a échoué, mais n'essayez pas d'invoquer un débogueur.

+0

Cela fonctionne à merveille! Merci! – HitLikeAHammer

-1

Tout d'abord, vérifiez si votre configuration contient la clé que vous cherchez, puis les envelopper dans une prise d'essai, puis vérifiez si elle est un entier valide:

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

Ok, je pense que je l'ai. Dans mon service, j'ai le code qui ressemble à ceci dans le constructeur:

config = ConfigurationManager.GetSection ("MyCustomConfigSection") en tant que MyCustomConfigSectionHandler;

C'est là que l'erreur est levée. Je peux attraper l'erreur et l'enregistrer. L'erreur doit être réenregistrée afin d'empêcher le service de continuer. Cela provoque toujours le mauvais comportement, mais au moins, je peux enregistrer l'erreur informant ainsi l'utilisateur de la raison pour laquelle le service n'a pas commencé

+0

Pas besoin de re-lancer, juste sortir avec le code d'erreur - voir ma réponse. –