Vedo due opzioni che possono essere utilizzate ai fini della centralizzazione della gestione delle eccezioni in TPL: 1. Utilizzo di Eccezione attività non osservata evento di Utilità di pianificazione. 2. Utilizzo di continuazioni per attività con stato di errore.
Utilizzo dell'evento Eccezione attività non osservata di Utilità di pianificazione.
L'utilità di pianificazione ha un evento UnobservedTaskException a cui è possibile iscriversi utilizzando l'operatore + =.
- Nota 1: Nel corpo del gestore è necessario fare la chiamata SetObserved() su argomenti UnobservedTaskExceptionEventArgs per notificare scheduler che un'eccezione è stata gestita.
- Nota 2: il gestore viene chiamato quando le attività sono state raccolte dal garbage collector.
- Nota 3: Se si attende l'attività, si sarà comunque obbligati a proteggere l'attesa tramite try/catch block.
- Nota 4: la politica predefinita per le eccezioni di attività non gestite in .Net 4.0 e 4.5 è diversa.
Riepilogo: questo approccio è utile per le attività "fire-and-forget" e per l'acquisizione di eccezioni evase dal criterio di gestione delle eccezioni centralizzato.
Utilizzo di continuazioni per attività con stato di errore.
Con TPL è possibile associare azioni all'attività utilizzando il metodo ContinueWith() che accetta l'azione di collegamento e l'opzione di continuazione. Questa azione verrà chiamata dopo la chiusura dell'attività e solo nei casi specificati dall'opzione. In particolare:
t.ContinueWith(c => { /* exception handling code */ }, TaskContinuationOptions.OnlyOnFaulted);
installa la continuazione con il codice di gestione delle eccezioni al Task t. Questo codice verrà eseguito solo nel caso in cui l'attività t sia stata interrotta a causa dell'eccezione non gestita.
- Nota 1: Ottieni il valore di eccezione nel codice di gestione delle eccezioni. Altrimenti sarà gorgogliato.
- Nota 2: il codice di gestione delle eccezioni verrà chiamato immediatamente dopo la chiusura dell'attività.
- Nota 3: Se l'eccezione è stata ottenuta nel codice di gestione delle eccezioni, verrà considerata come gestita, il blocco try/catch sull'attesa in attesa non sarà in grado di catturarlo.
Penso che per la gestione centralizzata delle eccezioni sia preferibile utilizzare Attività personalizzate ereditate da Attività con gestore di eccezioni aggiunto via continuazione. E accompagna questo approccio utilizzando l'evento Eccezione attività non osservato di Utilità di pianificazione per rilevare i tentativi di utilizzare attività non personalizzate.
La soluzione aggiornata funziona benissimo per quanto posso dire. Perché così poche persone hanno questo problema? –
Sarei molto gentile da parte tua se potessi includere anche il codice dal tuo blog qui. – Nifle
@Buu Nguyen Ciao, ho fatto qualcosa basandomi sul tuo approccio qui: http://stackoverflow.com/questions/11831844/unobservedtaskexception-being-throw-but-it-is-handled-by-a-taskscheduler-unobser/11908212 # 11908212 Grazie mille. Sperando che C# abbia qualcosa di meglio. – newway