Nunca he estado del todo contento con la forma en que funciona el manejo de excepciones, hay muchas excepciones y try/catch trae a la mesa (desenrollado de pila, etc.), pero parece romper mucho el modelo OO en el proceso .¿Reducir el código de manejo de error duplicado en C#?
De todos modos, aquí está el problema:
Digamos que usted tiene un poco de clase que envuelve o incluye las operaciones de IO de archivos en red (por ejemplo, la lectura y la escritura en algún archivo en algún ruta UNC en particular en algún lugar). Por diversas razones, no desea que esas operaciones de IO fallen, por lo que si detecta que fallan, las vuelve a intentar y las vuelve a intentar hasta que tengan éxito o llegue a un tiempo de espera excedido. Ya tengo una clase RetryTimer conveniente que puedo instanciar y usar para dormir el hilo actual entre reintentos y determinar cuándo ha transcurrido el tiempo de espera, etc.
El problema es que usted tiene un montón de operaciones IO en varios métodos de esta clase, y necesita envolver a cada uno de ellos en la lógica try-catch/retry.
He aquí un fragmento de código de ejemplo:
RetryTimer fileIORetryTimer = new RetryTimer(TimeSpan.FromHours(10));
bool success = false;
while (!success)
{
try
{
// do some file IO which may succeed or fail
success = true;
}
catch (IOException e)
{
if (fileIORetryTimer.HasExceededRetryTimeout)
{
throw e;
}
fileIORetryTimer.SleepUntilNextRetry();
}
}
Así que, ¿cómo evitar la duplicación de la mayor parte de este código para cada operación IO archivo durante la clase? Mi solución fue usar bloques de delegados anónimos y un único método en la clase que ejecutó el bloque de delegados que se le pasó. Esto me permitió hacer cosas como esta en otros métodos:
this.RetryFileIO(delegate()
{
// some code block
});
me gusta esto de alguna manera, pero deja mucho que desear. Me gustaría escuchar cómo otras personas resolverían este tipo de problema.
Solo un FYI general: es [casi * siempre * mejor] (http://philosopherdeveloper.wordpress.com/2010/05/05/re-throwing-caught-exceptions/) simplemente 'throw;' en su lugar de 'throw e;' –