2015-08-07 12 views
6

Qual è il modo migliore per restituire un'attività che non ha un parametro di tipo generico? In altre parole un'attività che rappresenta un'operazione che non restituisce nulla o restituisce void?Che cosa è un'alternativa per Task.FromResult <T>() per le attività che rappresentano le operazioni che restituiscono l'annullamento

In altre parole, Cerco alternative per il seguente:

T value = default(T); 
return Task.FromResult<T>(value); // and 

var tcs = new TaskCompletionSource<T>(); 
tcs.SetResult(value); 
return tcs.Task; 

Ma per le attività che rappresentano operazioni che non dovrebbero restituire nulla.

risposta

9

Task<T> estende Task - quindi è ragionevolmente comune utilizzare solo Task.FromResult<object> e fornire un risultato vuoto. Per esempio:

Task ret = Task.FromResult<object>(null); 

(O utilizzare un tipo di valore - in realtà non ha molta importanza.)

Naturalmente, come le attività sono immutabili si potrebbe creare un'istanza Singleton questo e tornare ogni volta si desidera restituire un compito completato. (Credo che sia ciò che fa l'infrastruttura async/await, infatti - o almeno lo ha fatto nelle versioni beta ...)

Come si è notato, è possibile utilizzare Task.CompletedTask, ma solo se si sta utilizzando .NET 4.6. (In realtà, non è chiaro se supporta .NET 4.5 o meno - la documentazione mostra ".NET Framework 4.6 e 4.5" come numero di versione, ma poi dice "Supportato in: 4.6" ...)

+0

Grazie. Mi ci è voluto un po 'di tempo per votare come risposta corretta perché stavo pensando alle implicazioni. Mentre la firma lo consente, ero preoccupato di cosa accadrebbe se il consumatore di quell'attività si aspettasse che l'attività restituisse qualcosa. Ma hai ragione. Sono autore del compito e so che non restituisce nulla. Non importa ciò che il consumatore si aspetta nell'ignoranza. Può scegliere di aspettarlo o semplicemente buttarlo via (fuoco e dimenticare). In entrambi i casi, funzionerà. –

+2

Prima di 4.6 è possibile chiamare Task.WhenAll() senza argomenti per esporre Task.CompletedTask che è interno fino a 4.6 –

+0

'Task.CompletedTask' non sembra apparire in portatile a partire da febbraio 2017. – Shimmy

9

I non sono sicuro se questo è strettamente idiomatico, ma io uso Task.CompletedTask per questo. È comunemente usato un Task.FromResult, ma in tutti gli scenari posso pensare che CompletedTask funzioni in modo identico e abbia più senso semanticamente.

+2

Yup - questo è il migliore approccio da .NET 4.6 in poi. –

+0

@ Asad: Sì, l'ho visto stamattina. E 'stato aggiunto in 4.6 ed è zucchero sintattico per 'FromResult'. –

+1

@ WaterCoolerv2 Beh, è ​​solo una nuova proprietà, non proprio zucchero di sintassi; e guardando la [fonte di riferimento] (http://referencesource.microsoft.com/#mscorlib/system/threading/Tasks/Task.cs,66f1c3e3e272f591) non sembra restituire un 'Task.FromResult'. Tuttavia, il fatto che sia 4.6 rende "FromResult" la scelta giusta. –