2012-08-23 12 views
37

Sto cercando di avvolgere la mia testa intorno al TPL, le nuove funzioni async/await in C# 5, ei misteri della TaskCompletionSource.TaskCompletionSource: Quando usare SetResult() contro TrySetResult(), ecc

Una cosa che non mi è chiaro è quando utilizzare SetResult, SetException, e SetCancel contro TrySetResult, TrySetException e TrySetCancel.

Questo è ciò che ha da dire MSDN:

Questa operazione restituirà false se l'attività è già in uno dei tre stati finali: RanToCompletion, Faulted, o annullato.

Questo metodo restituisce anche false se l'attività sottostante ha già eliminato.

Ok, ho capito, ma in realtà non offre alcuna indicazione su quando o perché usarne uno sull'altro.

Quindi, qual è l'affare?

risposta

46

ho sospetto il punto è che se c'è solo una cosa che sarà fissando il risultato, basta chiamare SetResult ecc Se si finisce per chiamare SetResult due volte, che indica un bug. (Analogamente se lo TaskCompletionSource è stato eliminato)

Se si dispone di più thread, è possibile che si stia tentando di impostare il risultato contemporaneamente (ad es. È lì per indicare il primo risultato tra diverse chiamate di servizio web parallele) quindi utilizzare TrySetResult, poiché è assolutamente ragionevole che più thread "provino" a impostare il risultato, ignorando se un altro thread lo ha già impostato.

Non ho visto alcuna guida ufficiale su di esso, ma avrebbe avuto senso.

+8

vale a dire, in realtà, l'unica ragione per cui è necessario chiamare "TrySetResult" è se si imposta il risultato più di una volta. 'SetResult'" completa "l'associata' Task' quindi chiamare 'SetResult' di nuovo proverebbe a impostare il risultato' Task 'dopo che l'attività è stata completata. ('SetResult' blocca fino a che il' Task' non termina - così come 'TrySetResult') Se si chiama" SetResult "solo una volta, non si dovrebbe mai aver bisogno di' TrySetResult'. FWIW. 'SetResult' catene a' TrySetResult' ... –

+0

Grazie ragazzi, avete molto senso! – HolySamosa

+0

Si noti inoltre che SetResult restituisce 'void' mentre TrySetResult restituisce' bool' quindi se si desidera eseguire condizionalmente qualcosa in base allo stato dell'attività, quindi 'TrySetResult' è sia di controllo che di set allo stesso tempo (atomicamente?). – chakrit

Problemi correlati