È stato utile?

Soluzione

Non c'è un TaskCompletionSource non generico e considerando tutto ciò che desideri è un'attività senza risultato, il risultato non ha importanza. Il chiamante non lo sa e non importa in questo caso che l'attività sia in realtà un Task<object>, il chiamante è solo generacodicitagcode, e ottiene un'eccezione se ce n'è uno.Il chiamante non è consapevole del risultato effettivo.

Questo ovviamente è facilitato dal fatto che await eredita da Task<T>


.

È anche comune trovare un Task che restituisce false o Task<bool> con 0.

Altri suggerimenti

Non esiste una classe TaskCompletionSource non generica per la creazione di istanze di Task che non sono istanze di Task<T>. Questo lascia due opzioni per il parametro tipo generico per TaskCompletionSource<T> quando non ti interessa (o non forniscono) il valore di ritorno:

    .
  1. Utilizzare un tipo esistente arbitrario, come object, come tipo di ritorno. Impostare il valore su null per indicare il completamento dell'attività.
  2. Utilizzare uno specifico tipo non pubblico e impostare il valore su null per indicare il completamento dell'attività.
  3. Quando creo un'istanza TaskCompletionSource<T> allo scopo di fornire un Task senza valore di ritorno, preferisco utilizzare un tipo non pubblico dedicato per garantire che il codice di consumo non scambiasse il Task restituito come un'istanza di Task<T> in cui il risultato ha significato.

    In primo luogo, definisco la seguente classe (può essere un private sealed class se è annidato all'interno di un altro tipo):

    internal sealed class VoidResult
    {
    }
    
    .

    Quindi, invece di utilizzare TaskCompletionSource<object> per la sorgente di completamento, utilizzo TaskCompletionSource<VoidResult>. Poiché il tipo VoidResult non è accessibile con il codice di chiamata, l'utente non sarà in grado di lanciare l'oggetto Task a un'istanza di Task<VoidResult>.

.

Non capisco particolarmente perché il metodo dovrebbe restituire Task anziché Task<object>

Poiché quando si ritorna Task<Object> significa che quando questo metodo lo completa produrrà un utile valore di tipo Object.In questo caso non stiamo producendo alcun risultato, ecco perché Stephen sceglie di tornare Task.

Se abbiamo a che fare con Func<Object>, il restituzione di Task<Object> sarebbe appropriato, poiché Func produrrà qualche risultato, possiamo scegliere di restituirlo.

.

Perché TaskCompletionSource<Object>, non TaskCompletionSource?

Perché non c'è niente del genere.Non esiste un TaskCompletionSource non generico.

Se è stato restituito un Task<object>, allora var result = await RunAsync(...) restituirebbe sempre null, dal momento che è quello che stai impostando il risultato in.

Il cliente non si preoccupa di questo, quindi restituisci un Task.

Idealmente, useresti un TaskCompletionSource internamente, invece di un TaskCompletionSource<object>, e semplicemente chiamare qualcosa come SetCompleted() anziché SetResult(null).Ma tale tipo non esiste.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top