2015-05-15 5 views
10

Sto leggendo il codice sorgente di estensioni interattive e hanno trovato un line che non riesco a capire:C# Compiti - Perché è necessario una linea noop in questo caso

public static Task<bool> UsingEnumerator(this Task<bool> task, IDisposable disposable) 
{ 
    task.ContinueWith(t => 
    { 
     if (t.IsFaulted) 
     { 
      var ignored = t.Exception; // don't remove! 
     } 

     if (t.IsFaulted || t.IsCanceled || !t.Result) 
      disposable.Dispose(); 
    }, TaskContinuationOptions.ExecuteSynchronously); 

    return task; 
} 

anche io non vedo alcuna osservazioni rilevanti in i documenti per le proprietà IsFaulted o Exception.

Perché questa riga var ignored = t.Exception; // don't remove! è necessaria in questo contesto?

Una domanda correlata: ho pensato che tali linee sono ottimizzate nella modalità di rilascio, ma dato il commento e l'intento qui non è il caso (se il codice è corretto). Quindi perché questa linea rimane nella modalità di rilascio?

+3

In .net 4 il finalizzatore di attività genera un'eccezione se un'attività è in errore ma non si accede alla proprietà 'Exception'. – Lee

+0

@Lee grazie! Questo in realtà è scritto nei documenti per la proprietà 'Exception' ma non l'ho capito nella prima lettura. –

+1

rispetto alla sua rimozione nei build di rilascio, il locale 'ignorato' verrà rimosso, ma' t.Exception' verrà risolto al suo valore (perché potrebbe, e in questo caso, causare effetti collaterali) è solo che il valore di ritorno viene rilasciato sul pavimento nelle build di rilascio invece di essere memorizzato in una variabile non letta. – Servy

risposta

7

Questa riga rappresenta la differenza tra un'eccezione osservata e una non osservata.

In .Net 4.0 un'attività con un'eccezione inosservata genera un UnobservedTaskException e abbattere l'intera applicazione:

"Se non si attende su un compito che si propaga un'eccezione, o accedere la sua eccezione proprietà, l'eccezione viene escalizzata in base alla politica delle eccezioni .NET quando l'attività viene raccolta tramite garbage. "

Da Exception Handling (Task Parallel Library)

che è stato cambiato in Net 4.5 con async-await, anche se è possibile ottenere il vecchio comportamento indietro con l'app.config (<ThrowUnobservedTaskExceptions enabled="true"/>).

C'è anche un evento (TaskScheduler.UnobservedTaskException) che consente di gestire tali attività in errore prima che l'applicazione si blocchi. Questo evento è ancora in fase di sviluppo in .Net 4.5 e versioni successive.

+0

@Servy Non concordo. È stato modificato perché è stato richiesto "async-await" per abbandonare le attività comuni che non erano precedenti. – i3arnon