2009-08-25 10 views
10

Estoy escribiendo un servicio WCF en C#. Inicialmente, mi implementación tenía un constructor estático para realizar una inicialización única, pero parte de la inicialización que se realiza podría fallar (temporalmente).Inicialización de tipo (constructor estático) manejo de excepciones

Parece que los constructores estáticos solo se invocan una vez, incluso si el primer intento (fallido) arrojó una excepción. Cualquier intento posterior de instanciar mi clase fallará inmediatamente con un TypeInitializationException sin que el código se esté ejecutando realmente.

La especificación de lenguaje C# indica que un constructor estático se llama como mucho una vez, pero básicamente esto hace una excepción allí un error que no se puede recuperar, incluso si lo atrapa?

¿Falta algo aquí? Supongo que debería mover cualquier cosa remotamente peligrosa al constructor de la instancia del servicio y verificar manualmente si la inicialización de la clase ya se completó exitosamente antes o no.

Respuesta

3

Así podría envolver las partes críticas en try/catch y al menos eso significa que el tipo no se inicializará, pero seguramente si el código de inicialización es tan crítico, entonces este comportamiento es realmente bueno - el tipo no es utilizable en este estado no inicializado.

La otra opción es hacerlo como singleton: cada vez que intente obtener la instancia, puede crear el tipo correctamente, hasta que tenga éxito, incluso si falla la primera vez.

Todavía necesitaría algún tipo de manejo de error en la persona que llama en caso de que la instancia le devuelva nulo el primer (o segundo, etc.) tiempo.

Editar: Y si no desea un producto único, a continuación, sólo tiene su constructor de instancias inicializar las partes estáticas

por ejemplo,

private object _lock = new object() 
private bool _initialized; 

public T() 
{ 
    lock(_lock) 
    { 
     if(!_initialized) 
     { 
     try 
     { 
      //Do static stuff here 
     } 
     catch(Exception ex_) 
     { 
      //Handle exception 
     } 
     } 
    } 
} 
+1

Eso es en realidad lo que tengo ahora, excepto que utilizo un bloqueo verificado doble y mi' _inicializado' bool es 'volátil' (no debería ser necesario sin doble bloqueo comprobado) – Thorarin

3

La lección aquí es bastante simple: no haga nada en un constructor estático que pueda fallar razonablemente.

+0

MSDN menciona que el tipo no se inicializará, pero no entendí de inmediato que sería imposible crear una instancia. Hubiera esperado una advertencia más explícita sobre esto realmente. No es un gran problema, pero hace que los constructores estáticos sean mucho menos útiles :( – Thorarin

+0

@Thorarin - solo durante el tiempo de vida de AppDomain. 'Type no se inicializará durante el tiempo de vida del dominio de la aplicación en la que se ejecuta tu programa 'de MSDN http://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx – VoodooChild

0

La solución que he utilizado en el pasado es la creación de un Singleton. Haga que un constructor estático falle si y solo si el error significa que no se puede ejecutar la aplicación completa.

Cuestiones relacionadas