Al tener una secuencia compleja de tareas, la implementación del manejo de errores puede hinchar rápidamente el código al usar bloques try/catch y cosas como receptores Choice en PortSet<ActualResult, Exception>
para cada pequeña tarea.CCR: mejor práctica para manejar errores usando causalidades
Afortunadamente el CCR parece ofrecer un mecanismo para manejar las excepciones de una manera más general para un gráfico de tareas: causalidades. Un ejemplo típico se parece a esto:
Port<Exception> exceptionPort = new Port<Exception>();
Dispatcher.AddCausality(new Causality("some job", exceptionPort));
Arbiter.Activate(
dispatcherQueue,
Arbiter.Receive(false, exceptionPort, ex => Console.WriteLine(ex)));
// now schedule the real tasks
En mi caso, tengo una aplicación intensiva de computación utilizando el CCR para implementar una dispersión/agrupación escenario, la división de "puestos de trabajo" en un montón de tareas paralelizados. (Además, más de uno de estos trabajos puede ejecutarse al mismo tiempo). En caso de que una tarea falle, quiero detener todas las tareas restantes en el trabajo, pero no cualquier otro trabajo. (Los resultados no me sirven si me falta una parte del rompecabezas, por lo que continuar trabajando en esto sería solo una pérdida de tiempo de CPU.)
La pregunta es cuál sería la mejor manera de implementar la parada.
Una idea sería:
- Crear una sola instancia
Dispatcher
y mantenerlo durante toda la vida de la aplicación. - Crea un nuevo
DispatcherQueue
por cada "trabajo" (un grupo de tareas). Agregue elCausality
inmediatamente después de crear elDispatcherQueue
. - En el controlador para la cola de excepciones, llame al
Suspend()
en elDispatcherQueue
. - Antes de eliminar la cola del despachador, elimine la causalidad.
Me pregunto si esta sugerencia se puede considerar la mejor práctica, o si hay un mejor enfoque para hacer frente a ese escenario, probablemente bastante común.