2011-08-26 9 views
6

Estoy tratando de escribir un método Dispose que tiene el poder para lanzar una excepción.Detectar excepción en el bloque finally

El dispose se invoca en un patrón try-finally, a través de un comunicado using:

using(var widget = new Widget()) 
{ 
    widget.DoYourThing(); 
} 

El problema es que si se produce una excepción por el método Dispose, reemplaza cualquier excepción que pueda haber sido levantado durante la cuerpo del bloque using. Por lo general, esta excepción es menos útil que la arrojada en el cuerpo.

Lo que me gustaría es escribir el método Dispose de tal manera que se trague sus propias excepciones si ya hay una excepción en curso. Algo como el siguiente sería ideal:

protected virtual void Dispose(bool disposing) 
{ 
    try 
    { 
     this.Shutdown(); 
    } 
    catch(Exception) 
    { 
     this.Abort(); 

     // Rethrow the exception if there is not one already in progress. 
     if(!Runtime.IsHandlingException) 
     { 
      throw; 
     } 
    } 
} 

¿Hay algo que pueda proporcionar esta información?

+5

Aquí hay un problema general: si está implementando el patrón Dispose, su método Dipose puede invocarse en la secuencia del finalizador. A su vez, la regla para los finalizadores es que * no deberías arrojar *. Esto tiende a llevar a la conclusión de que los métodos de eliminación tampoco deberían arrojar. –

+2

"Esto tiende a llevar a la conclusión de que los métodos Dispose no deberían arrojar tampoco" - evite tirar si puede, por supuesto, pero algunas implementaciones de Dispose deben arrojarse. Por ejemplo, el método Dispose de FileStream intentará eliminar cualquier dato almacenado y se lanzará si falla el color. Ignorar silenciosamente una falla en la eliminación de datos claramente no es una opción, entonces concluiría que, en el caso general, debe esperar que un método de Disposición pueda arrojar. – Joe

+0

Actualmente, mi implementación 'Dispose' se lleva todas las excepciones planteadas por métodos internos, como una buena implementación. Solo causa problemas, ya que las excepciones se pierden. Tal vez me inclinaría a escribir las excepciones a un rastreo de diagnóstico y mantener la implementación tal como está. –

Respuesta

0
+0

Entonces, la lección es "no use un objeto desechable en una declaración' using' si la llamada 'Dispose' puede arrojar una excepción" o "no escribe' Dispose' métodos que pueden arrojar excepciones "? Tal vez ambos? –

1

¿Es realmente necesario para el método Dispose para poder lanzar una excepción?

Quizás debería crear otro método de eliminación con un nombre diferente, y haga que arroje una excepción si es necesario. Luego implemente Dispose llamando a ese otro método, envuelto en un bloque try que tragará la excepción para que Dispose nunca lo arroje.

+0

Espero que pueda ver en mi ejemplo que 'Shutdown' es exactamente el método que describe. Mi implementación actual se traga todas las excepciones planteadas por este método, pero algunas de ellas son valiosas. –

Cuestiones relacionadas