2011-02-10 9 views
5

Sto cercando di impedire che un'attività prosegua se la prima parte fallisce.Prevent Task.ContinueWith in caso di eccezione

Il mio codice sembra che:

Task listener = Task.Factory.StartNew(openConnection).ContinueWith((t) => listenForNumber()); 

    void openConnection() 
    { 
     try 
     { 
      //stuff 
     } 
     catch 
     { 
      //morestuff 
     } 
    } 

    void listenForNumber() 
    { 
     //even more stuff 
    } 

Ora listenForNuber() non deve essere eseguita se OpenConnection() entra nel blocco catch

ho provato ContinueWith((t) => listenForNumber(),TaskContinuationOptions.NotOnFaulted);

Ma senza successo, qualsiasi aiuto ? :(

Grazie

+3

Hai rilanciato o ingoiato l'eccezione all'interno di tale blocco? –

risposta

8

TaskContiuationOptions.NotOnFaulted ovviamente non hanno alcun effetto a meno che il metodo è in errore, vale a dire un eccezione generata durante la sua esecuzione è stata gestita.

Nel tuo blocco catch, si dovrebbe ri-generare l'eccezione (e preservare la traccia dello stack) usando la dichiarazione throw; dopo aver eseguito il tuo lavoro (qualche ripulitura forse) - altrimenti l'eccezione non verrà lanciata di nuovo, quindi il tuo metodo non sarà considerato come "guasto"

+0

Ok ma se riporto l'eccezione dove è il posto migliore per ingoiarlo (e come) quindi non ottengo un'eccezione Aggregated o un'eccezione non gestita dal codice utente? Non ho bisogno di gestirlo di nuovo come tutto è già stato fatto nel primo blocco catch. – Ekoms

+0

@Ekoms: per quanto ne so, l'AggregateException viene lanciata solo se si accede alla proprietà 'Result' dell'attività. Questo dovrebbe essere l'unico punto in cui puoi ingoiare l'eccezione, ma prima dovresti controllare se è davvero l'eccezione che intendi inghiottire, e non solo qualche eccezione inaspettata. – ShdNx

1

Devi lanciare l'eccezione nel tuo metodo di attività L non sa che il metodo ha fallito, a meno che non rilevi un'eccezione.

Sarà comunque necessario disporre di un metodo di continuazione per il caso guasto. Questo potrebbe essere un metodo semplice che registra l'eccezione.

Se non si dispone di un metodo di continuazione per l'eccezione, si ottengono eccezioni non gestite nell'applicazione quando il metodo dell'attività genera un'eccezione.

2

Creare un helper del metodo di estensione.

public static void PropagateExceptions(this Task task) 
{ 
    if (task == null) 
     throw new ArgumentNullException("task"); 
    if (!task.IsCompleted) 
     throw new InvalidOperationException("The task has not completed yet."); 

    if (task.IsFaulted) 
     task.Wait(); 
} 

quindi chiamare il metodo di estensione PropagateExceptions() prima di eseguire qualsiasi codice. Anche il metodo PropagateExceptions() ripeterà se l'attività è stata annullata.

t1.ContinueWith(t => { 
    t.PropagateExceptions(); 
    listenForNumber(); 
}); 
Problemi correlati