2015-08-07 17 views
6

Jaki jest najlepszy sposób na zwrócenie zadania, które nie ma parametru rodzajowego? Innymi słowy zadanie reprezentujące operację, która niczego nie zwraca ani nie zwraca void?Co to jest alternatywa dla Task.FromResult <T>() dla zadań reprezentujących operacje zwracające nieważne

Innymi słowy, szukam alternatyw dla następujących:

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

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

Ale dla zadań, które reprezentują operacje, które nie mają nic do powrotu.

Odpowiedz

9

Task<T> rozszerza Task - więc rozsądnie jest używać tylko Task.FromResult<object> i podać pusty wynik. Na przykład:

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

(Lub użyć typ wartości - to naprawdę nie ma większego znaczenia.)

Oczywiście, jako zadania są niezmienne można utworzyć instancję singleton to i wrócić za każdym razem chcesz zwrócić zadanie ukończone. (Sądzę, że tak właśnie jest w przypadku infrastruktury async/await - lub przynajmniej w wersjach beta ...)

Jak zauważył Asad, można użyć Task.CompletedTask, ale tylko wtedy, gdy kierujesz na .NET 4.6. (Właściwie nie jest jasne, czy obsługuje on .NET 4.5, czy nie - dokumentacja pokazuje ".NET Framework 4.6 i 4.5" jako numer wersji, ale potem mówi "Obsługiwane w: 4.6" ...)

+0

Dziękuję. Zajęło mi trochę czasu, aby głosować to jako poprawna odpowiedź, ponieważ myślałem o konsekwencjach. Chociaż podpis na to pozwala, martwiłem się, co by się stało, gdyby konsument tego zadania oczekiwał, że zadanie zwróci coś. Ale masz rację. Ja tworzę to zadanie i wiem, że nic nie zwraca. Nie ma znaczenia, czego konsument oczekuje od niewiedzy. Może zdecydować się na to poczekać lub po prostu go wyrzucić (ogień i zapomnieć). Tak czy inaczej, to zadziała. –

+2

Wcześniej do 4.6 można wywoływać Task.WhenAll() bez argumentów, aby eksponować Task.CompletedTask, która jest wewnętrzna do 4.6 –

+0

'Task.CompletedTask' nie wydaje się być przenośna od lutego 2017. – Shimmy

9

I nie jestem pewien, czy jest to ściśle idiomatyczne, ale używam do tego Task.CompletedTask. Często używany jest kod Task.FromResult, ale we wszystkich scenariuszach mogę myśleć o tym, że CompletedTask działa identycznie i ma większy sens semantycznie.

+2

Yup - to najlepsze podejście od .NET 4.6 i później. –

+0

@Asad: Tak, widziałem to dziś rano. Został dodany w wersji 4.6 i jest syntaktycznym cukrem dla 'FromResult'. –

+1

@ WaterCoolerv2 Cóż, to tylko nowa właściwość, a nie tak naprawdę cukier składniowy; i patrząc na [źródło odniesienia] (http://referencesource.microsoft.com/#mscorlib/system/threading/Tasks/Task.cs,66f1c3e3e272f591) wydaje się, że nie zwraca on 'Task.FromResult'. Mimo to fakt, że wynosi on tylko 4.6, sprawia, że ​​'FromResult' jest właściwym wyborem. –

Powiązane problemy