Gestión de procesos
Estructuras para la gestión de tareas.
Esta librería tiene una estructura para el registro y gestión de tareas. Una tarea puede ser considerada como cualquier secuencia de operaciones que están metidas dentro de un Thread propio. Los objetivos a conseguir son:
- Poder mandar eventos a la tareas.
- Poder tener acceso desde todas las clases de la tarea al evento lanzado sin tener que propagar el evento por todos los metodos que intervienene en la tarea.
- Centralizar todas las tareas para poder tener comunicación con ellas conjuntamente. Es decir, poder mandarles eventos y/o recoger respuestas de forma conjunta.
Registro de la tarea.
Hay una clase donde debe registrarse un proceso cuando este se lanza. Esto permitirá tenerlo accesible continuamente hasta que este muera. De igual forma el proceso al acabar debe eliminarse del registro. La clase para el registro es RasterTaskQueue y la forma de realizar esto es la siguiente:
public void run() {
//Comienza nuestra tarea
RasterTaskQueue.register(rasterTask); //Registro de la tarea
*............*
//Finaliza nuestra tarea
RasterTaskQueue.remove(rasterTask); //Eliminamos la tarea del registro
}
El objeto rasterTask es un objeto de tipo RasterTask. Este debe ser inicializado como variable de instancia de la forma:
private RasterTask rasterTask = new RasterTask(this);
Hay que tener en cuenta que hay que pasarle como parámetro a la tarea. Esta parámetro en el constructor espera un Object Otra cosa importante es eliminar el proceso de la cosa siempre. Para esto hay que asegurarse que se ejecute la sentencia RasterTaskQueue.remove aunque se produzca una excepción y el proceso se aborte abruptamente. Por ello es recomendable meterla en un bloque finally en las excepciones capturadas además de al final del proceso.
Envio de eventos.
Para mandarle eventos a la tarea se hace a través del objeto RasterTask usando un objeto que herede de EventObject. Por ejemplo si queremos definir un evento de cancelación (este ya existe por lo que no habría que hacer otro) definiremos un objeto CancelEvent que herede de EventObject.
public class CancelEvent extends EventObject {
private static final long serialVersionUID = 7564626429497930401L;
public CancelEvent(Object source) {
super(source);
}
}
Para mandarle el evento a la tarea meteremos dentro de un listener o de la forma definida por nosotros el código siguiente.
rasterTask.setEvent(new CancelEvent(this));
rasterTask es el objeto de tipo RasterTask que se ha definido dentro del proceso.
Captura de eventos.
Desde cualquier parte de la tarea podemos recoger el evento producido accediendo al objeto RasterTask. Esto puede hacerse pidiendoselo al RasterTaskQueue de forma estática. El truco de este método es que se pide a través del identificador de Thread. Es por esto que cualquier clase dentro del Thread sabe como pedirlo ya que todas saben en que Thread se encuentran.
RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
Ahora ya solo quedaría tratar el evento dentro del proceso pesados que queramos.
for(.......) { //Ejemplo de proceso pesado
//En cada iteración comprobamos si el evento sigue siendo null. Si no lo es lo gestionamos
if(task.getEvent() != null)
task.manageEvent(task.getEvent());
}
RasterTask tiene una llamada manageEvent que realiza acciones por defecto para un evento concreto. En principio no tiene porque gastarse esto ya que puede no coincidir con nuestro interés. Para el caso del cancelado de tareas el método manageEvent con parámetro EventCancel lanzará una excepción de java InterruptedException que debe capturarse siempre.