una try tipos sharp que personalizadas net generar existen excepción excepciones excepcion errores ejemplos como catch capturar c# .net exception

tipos - try catch c#



Lanzar múltiples excepciones en.Net/C# (5)

Dos formas de la parte superior de mi cabeza sería hacer una excepción personalizada y agregar las excepciones a esta clase y arrojar al final:

public class TaskExceptionList : Exception { public List<Exception> TaskExceptions { get; set; } public TaskExceptionList() { TaskExceptions = new List<Exception>(); } } public void DoTasks(MyTask[] taskList) { TaskExceptionList log = new TaskExceptionList(); foreach (MyTask task in taskList) { try { DoTask(task); } catch (Exception ex) { log.TaskExceptions.Add(ex); } } if (log.TaskExceptions.Count > 0) { throw log; } }

o devuelve true o false si las tareas fallaron y tienen una variable ''Out List''.

public bool TryDoTasks(MyTask[] taskList, out List<Exception> exceptions) { exceptions = new List<Exception>(); foreach (MyTask task in taskList) { try { DoTask(task); } catch (Exception ex) { exceptions.Add(ex); } } if (exceptions.Count > 0) { return false; } else { exceptions = null; return true; } }

En una aplicación en la que trabajo, cualquier error de lógica de negocios hace que se genere una excepción y el código de llamada maneja la excepción. Este patrón se usa en toda la aplicación y funciona bien.

Tengo una situación en la que trataré de ejecutar una serie de tareas comerciales desde dentro de la capa empresarial. El requisito para esto es que una falla de una tarea no debe causar que el proceso finalice. Otras tareas deberían ser capaces de ejecutar. En otras palabras, esta no es una operación atómica. El problema que tengo es que al final de la operación, deseo notificar al código de llamada que se produjo una excepción o excepciones lanzando una excepción. Considere el siguiente fragmento de código psuedo:

function DoTasks(MyTask[] taskList) { foreach(MyTask task in taskList) { try { DoTask(task); } catch(Exception ex) { log.add(ex); } } //I want to throw something here if any exception occurred }

¿Qué arrojo? Me he encontrado con este patrón antes en mi carrera. En el pasado, conservé una lista de todas las excepciones, luego lancé una excepción que contiene todas las excepciones detectadas. Esto no parece ser el enfoque más elegante. Es importante preservar tantos detalles como sea posible de cada excepción para presentar al código de llamada.

¿Pensamientos?

Editar: la solución debe escribirse en .Net 3.5. No puedo usar ninguna biblioteca beta, o la excepción AggregateException en .Net 4.0 como lo menciona Bradley Grainger (a continuación) sería una buena solución para las excepciones de recolección.


Es posible que desee utilizar un BackgroundWorker para hacer esto por usted. Captura automáticamente y presenta cualquier excepción cuando se completa, que luego puede lanzar o iniciar sesión o hacer cualquier cosa con. Además, obtienes el beneficio de multihilo.

El BackgroundWorker es una buena envoltura alrededor del modelo de programación asincrónica del delegado .


Las extensiones de la Biblioteca de tareas paralelas para .NET (que formará parte de .NET 4.0 ) siguen el patrón sugerido en otras respuestas: recopilar todas las excepciones que se han lanzado a una clase AggregateException.

Al lanzar siempre el mismo tipo (si hay una excepción del trabajo infantil, o muchos), el código de llamada que maneja la excepción es más fácil de escribir.

En .NET 4.0 CTP, AggregateException tiene un constructor público (que toma IEnumerable<Exception> ); puede ser una buena opción para su aplicación.

Si tiene como objetivo .NET 3.5, considere clonar las partes de la clase System.Threading.AggregateException que necesita en su propio código, por ejemplo, algunos de los constructores y la propiedad InnerExceptions. (Puede colocar su clon en el System.Threading namespace dentro de su ensamblado, lo que podría causar confusión si lo expuso públicamente, pero facilitará la actualización a 4.0 más adelante). Cuando se lanza .NET 4.0, usted debería ser capaz de " actualice "al tipo de Marco eliminando el archivo de origen que contiene su clon de su proyecto, cambiando el proyecto para apuntar a la nueva versión de marco y la reconstrucción. Por supuesto, si hace esto, debe realizar un seguimiento de los cambios a esta clase con cuidado, ya que Microsoft lanza nuevos CTP, para que su código no sea incompatible. (Por ejemplo, esto parece una clase de propósito general útil, y podrían moverlo de System.Threading a System .) En el peor de los casos, puede cambiar el nombre del tipo y moverlo nuevamente a su propio espacio de nombres (esto es muy fácil con la mayoría de las herramientas de refactorización).


No hay una solución súper elegante aquí, pero algunas ideas:

  • Pase una función de controlador de errores como argumento a DoTasks para que el usuario pueda decidir si continuar
  • Use el rastreo para registrar errores a medida que ocurren
  • Concatenar los mensajes de las otras excepciones en el mensaje del conjunto de excepciones

Puede crear una Excepción personalizada que tenga una colección de Excepciones. Luego, en tu bloque de captura, simplemente agrégalo a esa colección. Al final de su proceso, verifique si el recuento de excepciones es> 0, luego envíe su excepción personalizada.