Capita non di rado in alcune applicazioni di avere la possibilità di interrompere qualche operazione “lunga” o “asincrona” a fronte della richiesta di qualche operatore sia esso un’utente comune o un agente software. Questa operazione spesso sottovalutata dovrebbe essere conclusa senza portare il sistema in uno stato inconsistente in tutti i sensi, per tutti i sensi intendo sia dal punto di vista “tecnico”(es:stabilità del processo, risorse etc..), sia dal punto di vista dello stato dei dati in questione(es:una griglia su un form).
Questo significa che qualunque sia il tipo di operazione da interrompere, questa deve essere conscia del fatto che qualcuno ha deciso che deve smettere di fare quello che sta facendo senza provocare danni.
Con questo problema si sono dovuti scontrare chiaramente il team delle Task Parallel Library(.NET 4.0), riguardo al problema di dover interrompere un’operazione asincrona/parallela.
A fronte di questo hanno deciso di creare un’insieme di classi preposte alla gestione delle “cancellazioni” di operazioni in modo “cooperativo”, tutto questo sotto il nome di “Cancellation Framework”.
Le classi principali che compongono questo framework sono: CancellationToken che verrà passata all’operazione “interrompibile” per informarla che qualcuno ha richiesto uno stop, e CancellationTokenSource che scatenerà l’interruzione.
La cosa molto interessante è la modalità di comunicazione tra CancellationTokenSource e CancellationTokens (potrebbero essere più di uno, potremmo richiedere lo stop a più operazioni asincrone/parallele contemporaneamente). Possiamo effettuare un polling sulla proprietà IsCancellationRequested dell’oggeto CancellationToken o registrare una callback che verrà eseguita alla richiesta della cancellazione.
Questi tipi di pattern sono già stati implementati in molte classi del framework, ma ogni implementazione ha sempre avuto un suo set di classi personalizzate. L’idea di avere un framework comune mi sembra ottima, sarebbe molto più facile scrivere codice più “generico” e adattabile a contesti diversi, oltre che corretto nella sua implementazione (ci sono molte cose non banali da gestire, la sincronizzazione etc…).
Per una più dettagliata spiegazione dell’argomento vi lascio il post del pfxTeam.