5

Soy nuevo en el desarrollo de software y también nuevo en stackoverflow, así que no me moleste.Excepciones no controladas en la biblioteca de clases C# para fines de registro

ANTECEDENTES: Estoy desarrollando una biblioteca de clases C# que procesa mensajes xml enviados por una aplicación de terceros a través de tcp/ip (usando sockets Async). Estoy usando com-interop para exponer la biblioteca de clase a una aplicación Vb6. Cuando la biblioteca C# procesa el xml que recibe sobre el socket, plantea varios eventos a los que se suscribe la aplicación vb6 consumidora (de esta forma, cuando finalmente reescribamos toda la aplicación en .Net ya habremos terminado con este componente).

PREGUNTA: Quiero ver todas las excepciones no controladas para FINES DE INSCRIPCIÓN ÚNICAMENTE. En una aplicación de winforms puede conectar un evento a AppDomain.CurrentDomain.UnhandledException y a Application.ThreadException. ¿No hay forma de obtener de manera similar los datos de excepción para registrar la información en una biblioteca de clases?

puntos importantes:

  • No estoy tratando de recuperarse de estas excepciones, pero sólo les registrar y dejar que la excepción propagar y bloquee la aplicación si es necesario.

  • Estoy haciendo todo lo posible para detectar todas las excepciones específicas localmente donde sepa que pueden ocurrir. Por lo tanto, mi propósito es simplemente registrar las excepciones verdaderamente inesperadas.

  • Sé que algunos dirán que este sería un mal patrón de diseño. Debo, en cambio, dejar que la persona que llama lidie con estas excepciones. El problema es que la aplicación vb6 no tiene un manejo de errores tan sólido como me gustaría. En primer lugar, quiero registrar el seguimiento de la pila para que si la aplicación vb6 se cuelga debido a mi dll, pueda ver el registro para recibir una alerta sobre las áreas potenciales de mi código C# que podrían necesitar modificaciones.

¿Alguien me puede dar alguna dirección? La mejor opción que he encontrado hasta ahora parece poner un bloque try try genérico en cada método público, registrar la excepción y luego lanzarla. Esto parece ser menos que ideal:

public void SomeMethod() 
{ 
    try 
    { 
     // try something here... 
    } 
    catch (Exception ex) 
    { 
     Log(ex); 
     throw; 
    } 
} 

Esto no sólo parece esto como un mal diseño, pero, además, no sé qué pasaría si una de las devoluciones de llamada asincrónicas provoca una excepción en un subproceso diferente que el método se llama en. ¿Este bloque general try/catch aún captaría tal excepción?

Gracias por cualquier ayuda.

EDIT: I, originalmente de la respuesta de @Eric J. como correcta, pero después de tratar de poner en práctica la solución que he encontrado que no va a funcionar bien con las devoluciones de llamada asincrónicos de la clase socket que estoy usando . Una vez que un subproceso de subprocesos se utiliza para desencadenar la devolución de llamada asincrónica, parece que no puedo detectar ninguna excepción que ocurra más adelante en la pila. ¿Necesitaré usar un marco AOP o hay alguna otra forma de detectar estas excepciones?

+0

El verdadero problema aquí era que no tenía un bloque de catch de nivel superior en mis funciones de devolución de llamada asíncronas. Dado que se ejecutan en subprocesos separados (subprocesos de grupo de subprocesos), sus excepciones no vuelven a aparecer en ningún otro lugar. AOP parece una buena solución para este escenario para evitar tantos bloques catch de alto nivel. Es algo en lo que pretendo invertir un poco de tiempo un poco más adelante. –

Respuesta

2

Si tiene un conjunto limitado de puntos de entrada a la biblioteca, considere hacer lo que sugiere: use una clase contenedora .NET o una biblioteca contenedora para realizar la interoperabilidad real y capturar/registrar la excepción en esa clase contenedora. Devuelve una excepción o código de error que la biblioteca VB6 llamante sabe cómo manejar (ya sea que reiniciar la excepción o no depende de lo que el código VB6 pueda manejar).

CrazyDart sugiere IOC, que es una alternativa interesante y válida pero también agrega complejidad y curva de aprendizaje inicialmente. Ciertamente, eche un vistazo al COI y considérelo como una posibilidad.

+0

No parece la solución ideal desde un punto de vista paradigmático, pero de nuevo, dado que mi tiempo parece ser la mejor opción para el presente proyecto. Gracias por el aporte. Solo por aclaración, ¿estás sugiriendo una capa adicional de envoltura, o solo lo que se requiere para hacer la interoperabilidad de com? –

+0

No, solo una capa única que hace la interoperabilidad COM y maneja las excepciones. Si tiene una gran cantidad de métodos para envolver, considere escribir un pequeño generador de código que, p. toma una lista de métodos por clase en COM y emite el código C# apropiado. Lo hice antes cuando envolví una capa comercial COM muy grande. Por otra parte, si es realmente grande, puede valer la pena invertir tiempo en IOC. –

+0

Gracias. Marcado como respuesta porque esta solución funciona mejor para mí en este momento. –

1

Puedes usar Castle Windsor y un interceptor para esto. Es una buena razón para usar COI en proyectos.

http://blog.andreloker.de/post/2009/02/20/Simple-AOP-integrating-interceptors-into-Windsor.aspx

Los he utilizado para el registro de excepción, tal como ha afirmado, y el rendimiento del registro ... entre otras muchas cosas que se utilizan interceptores para transacciones.

+0

He utilizado IOC en proyectos y personalmente creo que agrega el mayor beneficio en proyectos grandes con varios equipos responsables de diferentes áreas (diferentes preocupaciones). Sé que está entrando en el territorio de la guerra santa, simplemente compartiendo mi experiencia personal. –

+0

Todo tiene su lugar ... la pregunta es sobre un tema avanzado en mi humilde opinión y requiere un enfoque bastante avanzado para resolverlo correctamente. Estoy de acuerdo con algunas de las otras publicaciones que el AOP (casi lo mismo que los interceptores) es un enfoque válido. Filosóficamente, algunos eligen nunca plantar un árbol frutal. Yo siembro muchas veces. Más tarde tengo grandes cosechas. Muchas personas me preguntan cómo llegué a tener tantos árboles frutales de gran apariencia y les digo que los planto a menudo. Algunos mueren, y muchos no. Descuidar el aprendizaje porque es difícil es lo que hace que alguien sea apto para el servicio y los trabajos de mano de obra en lugar de la ingeniería. – CrazyDart

+0

Gracias CrazyDart. Estoy de acuerdo en que el problema parece bastante avanzado y puede requerir un enfoque avanzado. Lamentablemente, todo esto es nuevo para mí (he estado desarrollando solo durante 6 meses, a tiempo completo solo durante los últimos 2 meses). He marcado los marcos de AOP y Castle Windsor para el futuro. Dadas mis limitaciones de tiempo en el presente proyecto, me inclino por el enfoque de Eric. Si tiene alguna idea o inquietud sobre esto en el escenario anterior, siéntase libre de asesorarlo. Gracias de nuevo. –

1

Puede utilizar un marco AOP como Spring.NET o Unity, o bien mirar un producto como PostSharp (aunque nunca he probado PostSharp personalmente).

+0

Gracias por la información. Marcaré estos marcos y volveré a ellos en el futuro.Por ahora, me temo que la curva de aprendizaje puede ser demasiado grande para implementar dado mi tiempo limitado en el proyecto. –

Cuestiones relacionadas