jueves, 28 de agosto de 2014

Receta Multithreading en C# No. 1-11: Manejo de Excepciones en Threads

Índice

0. Introducción
1. Problema
2. Solución
3. Discusión de la Solución
4. Práctica: C#
5. Conclusiones
6. Glosario
7. Literatura & Enlaces

0. Introducción

En el estudio de esta receta multithreading comprenderemos el proceso de manejo de excepciones de threads en ejecución. Comprenderemos que esta tarea compromete sólo el manejo de las excepciones al interior del método adyacente al thread. En el ejemplo de la sección práctica simularemos la generación de una excepción que no cuenta con el correspondiente bloque try-catch, y otro método en donde el control de la excepción se lleva a cabo correctamente. Veremos que sucede con ambas situaciones.

1. Problema

Estudiar el manejo de las excepciones generadas en el interior de la implementación de un proceso asociado o adyacente a un thread.

2. Solución

En el cuerpo de la implementación de un método, como tradicionalmente lo hacemos, podemos especificar código de manejo de excepciones con las construcciones sintácticas C# diseñadas para este cometido: try-catch-finally.

3. Discusión de la Solución

En artículos C# ya hemos tratado en cierto grado de profundidad el manejo de excepciones. Aquí están los enlaces a los cinco artículos integrales de esta serie de excepciones:
[Nota: Hago la inclusión de estos enlaces para evitar extendernos en esta tema de las excepciones que en el contexto de esta receta se da por entendido.]

Por otro lado, y en particular, vale hacer mención de algunos aspectos importantes y cruciales en el manejo de excepciones con threads en ejecución. El primero de ellos es la advertencia encontrada en [1]:
«...It is very important to always place a try-catch block inside the thread because it is not possible to catch an exception outside a thread's code.»
Básicamente, lo anterior se puede resumir en que una excepción generada por un thread debe ser manipulada en el cuerpo de implementación del propio método adyacente, de lo contrario resulta imposible su manejo (como ya veremos en el ejemplo de la sección 4).

También hay que mencionar aquellas excepciones no manejables generadas, por ejemplo, con la suspensión de la ejecución de un thread (cfr. Abortar un Thread en Ejecución) o por la descarga de un dominio de aplicación [7]
  • ThreadAbortException [9]: Esta excepción es lanzada cuando se aborta la ejecución de un thread.
  • AppDomainUnloadedException [10]: Esta excepción se genera sobre un thread que ha intentado descargar un dominio de excepción (cfr. Creación de un Dominio de Aplicación).
Además como agregan en [7]:
«If any of these exceptions are unhandled in threads created by the common language runtime, the exception terminates the thread, but the common language runtime does not allow the exception to proceed further.»

4. Práctica: Código C#

En el siguiente ejemplo trataremos una excepción generada desde un método que se ejecuta sobre un thread independiente. Inclusive, demostraremos la generación de una excepción en el interior de un thread que no cuenta con un bloque de manejo excepciones try-catch para ver y distinguir su efecto ante la carencia de esta construcción sintáctica.

En las líneas 39-44 declaramos el método ThreadSinBloqueTryCatch. Este método genera una excepción tipo Exception, pero debemos resaltar que como se mencionó en la sección 3, es requisito indispensable que el cuerpo de implementación de un método adyacente a un thread cuenta con su propio bloque try-catch. Más adelante, líneas 47-61, se define el método ThreadConBloqueTryCatch, que a diferencia del método anterior, este sí cuenta con un bloque try-catch para manejar las excepciones que su lógica de implementación pudieran generar en el propio thread.


Continuando, en el punto de entrada de ejecución, Main, (líneas 8-35) se crea un primer thread de ejemplo para demostrar las capacidades de manejo de excepción interna del método ThreadConBloqueTryCatch: líneas 15, 18, y 21. Por el contrario, la operación de ejecución del thread t2 (línea 29) genera un error fatal en la aplicación que conlleva a su terminación abrupta. Esto se debe a la carencia del bloque try-catch del método ThreadSinBloqueTryCatch.

Compilación:


  1. csc /target:exe ManejoExcepcionesThread.cs

Ejecución assembly:


  1. .\ManejoExcepcionesThread.exe

> Prueba de ejecución (ideone.com).

> Prueba de ejecución (local):
Ejecución assembly ManejoExcepcionesThread.exe
Figura 1. Ejecución assembly ManejoExcepcionesThread.exe.

5. Conclusiones

Trabajamos en la práctica para la comprensión del manejo de excepciones en threads, tema de alta importancia debido a que su entendimiento nos permite construir aplicaciones multithreading tolerante a fallas lo que conlleva a la construcción de software más robusto y de nivel de diseño industrial. Con esta receta terminamos la serie de recetas dedicadas a los temas esenciales de threads en C#; para la próxima serie (capítulo 2) nos concentraremos en la sincronización de threads a lo largo de 9 entregas de este tipo.

6. Glosario

  • CLR
  • Descarga
  • Dominio de aplicación
  • Excepción
  • Exception
  • Multithreading
  • Sincronización
  • Thread
  • Tolerante a fallas

7. Literatura & Enlaces

[1]: Multithreading in C# 5.0 Cookbook by Eugene Agafonov. Copyright 2013 Eugene Agafonov, 978-1-84969-764-4.
[2]: Excepciones en C# - Parte 1: Introducción a las Excepciones | OrtizOL - Experiencias Construcción Software (xCSw) - http://ortizol.blogspot.com/2014/06/excepciones-en-csharp-parte-1-introduccion-a-las-excepciones.html
[3]: OrtizOL - Experiencias Construcción Software (xCSw): Excepciones en C# - Parte 2: Uso de Excepciones - http://ortizol.blogspot.com/2014/07/excepciones-en-csharp-parte-2-uso-de-excepciones.html
[4]: Excepciones en C# - Parte 3: Diseño de Excepciones Personalizadas | OrtizOL - Experiencias Construcción Software (xCSw) - http://ortizol.blogspot.com/2014/07/excepciones-en-csharp-parte-3-diseno-de-excepciones-personalizadas.html
[5]: Excepciones en C# - Parte 4: Propiedades de la Clase Base System.Exception | OrtizOL - Experiencias Construcción Software (xCSw) - http://ortizol.blogspot.com/2014/07/excepciones-en-csharp-parte-4-propiedades-de-la-clase-base-system.exception.html
[6]: Excepciones en C# - Parte 5: Ejemplos de Excepciones Comunes | OrtizOL - Experiencias Construcción Software (xCSw) - http://ortizol.blogspot.com/2014/07/excepciones-en-csharp-parte-5-ejemplos-de-excepciones-comunes.html
[7]: Exceptions in Managed Threads - http://msdn.microsoft.com/en-us/library/ms228965(v=vs.110).aspx
[8]: Receta Multithreading en C# No. 1-4: Abortar un Thread en Ejecución | OrtizOL - Experiencias Construcción Software (xCSw) - http://ortizol.blogspot.com/2014/06/receta-multithreading-en-csharp-no-1-4-abortar-un-thread-en-ejecucion.html
[9]: ThreadAbortException Class (System.Threading) - http://msdn.microsoft.com/en-us/library/system.threading.threadabortexception(v=vs.110).aspx
[10]: AppDomainUnloadedException Class (System) - http://msdn.microsoft.com/en-us/library/system.appdomainunloadedexception(v=vs.110).aspx
[11]: Receta No. 3-1 en C#: Creación de un Dominio de Aplicación (Application Domain) | OrtizOL - Experiencias Construcción Software (xCSw) - http://ortizol.blogspot.com/2014/05/receta-no-3-1-en-c-creacion-de-un.html


J

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.