2011-08-18 14 views
5

Quando si attende Task utilizzando Task.WaitAll e si specifica un timeout se TimeAll è scaduto, devo anche osservare separatamente eventuali attività non completate (ad esempio registrando una continuazione)?Task e Task.WaitAll con gestione delle eccezioni di timeout

This thread mi porta a pensare che la risposta sia sì, ma non ho trovato nient'altro che lo confermi.

var random = new Random(); 
var tasks = Enumerable.Range(0, 10).Select((i) => Task.Factory.StartNew(() => { 
     // Sleep 5-15 seconds 
     Thread.Sleep(random.Next(5000, 15000)); 
     throw new Exception("Some exception."); 
    } 
)).ToArray(); 

try { 
    // Wait for 10 seconds 
    Task.WaitAll(tasks, 10000); 
} catch (AggregateException) { 
    // Swallow 
} 

// Check to see how many tasks were unfinished 
tasks.Where(t => !t.IsCompleted).Count().Dump("Unfinished count: "); 

// Is this neccessary to avoid exceptions being thrown on the finalizer? 
foreach (Task task in tasks) { 
    task.ContinueWith(t => t.Exception, TaskContinuationOptions.OnlyOnFaulted); 
} 
+0

Quante eccezioni sono presenti in AggregateException che si verificano dopo WaitAll? –

+0

Qui la semplice sorgente di lib completa: http://stackoverflow.com/questions/11831844/unobservedtaskexception-being-throw-but-it-is-handled-by-a-taskscheduler-unobser –

risposta

0

Test con LINQPad v4.31 indica la risposta è sì, perché se si commento la foreach si ottiene un dialogo un'eccezione non gestita per ogni attività incompiuto.

Credo di capire perché questo è a questo punto, ma se qualcuno vuole provare una spiegazione più tecnica di questo comportamento con tutti i mezzi per farlo.

2

Per evitare l'arresto anomalo del finalizzatore, è necessario osservare le eccezioni generate dal corpo Task. Per osservare un'eccezione Task devi fare una delle seguenti:

  1. L'accesso alla proprietà eccezione
  2. chiamata Task.Wait/WaitAll/WaitAny
  3. Registrati una continuazione che funzionano solo se il compito incolpato

Ciò che è stato fatto è assolutamente necessario per evitare il crash del finalizzatore.