Mam interfejs z kilkoma funkcjami asynchronicznymi. Niektóre klasy implementujące interfejs nie mają na co czekać, a niektóre mogą po prostu wyrzucić. To trochę denerwujące ze wszystkimi ostrzeżeniami.
Gdy nie używasz await w funkcji asynchronicznej.
Czy można ukryć przekaz?
public async Task<object> test()
{
throw new NotImplementedException();
}
ostrzeżenie CS1998: Ta metoda asynchroniczna nie zawiera operatorów „await” i będzie działać synchronicznie. Rozważ użycie operatora „await”, aby oczekiwać nieblokujących wywołań API, lub „await Task.Run (...)”, aby wykonać pracę związaną z procesorem w wątku w tle.
c#
asynchronous
Szymon
źródło
źródło
Odpowiedzi:
Task
Myślę, że metody wracają .async
to szczegół implementacji, więc nie można go zastosować do metod interfejsu.W takich przypadkach można wykorzystać fakt, że
async
jest to szczegół implementacji.Jeśli nie masz nic do
await
roboty, możesz po prostu wrócićTask.FromResult
:W przypadku rzucania
NotImplementedException
procedura jest nieco bardziej rozwlekła:Jeśli masz wiele metod do rzucania
NotImplementedException
(co samo w sobie może wskazywać, że niektóre refaktoryzacje na poziomie projektu byłyby dobre), możesz zawrzeć te słowa w klasie pomocniczej:Klasa pomocnicza zmniejsza również ilość śmieci, które w przeciwnym razie musiałaby zbierać GC, ponieważ każda metoda z tym samym zwracanym typem może współużytkować swoje obiekty
Task
iNotImplementedException
.Mam kilka innych przykładów typu „stałej zadania” w mojej bibliotece AsyncEx .
źródło
Task
. Zamiast tego Twoja metoda wyrzuci, zanim jeszcze będzie miała szansę utworzyć plikTask
. Naprawdę uważam, że najlepszym wzorcem jest zdefiniowanieasync
metody bezawait
operatorów. Gwarantuje to, że kod w metodzie zostanie potraktowany jako częśćTask
.await Task.FromResult(0);
do swojej metody. Nie powinno to mieć żadnego znaczącego wpływu na wydajność (w przeciwieństwie do Task.Yield ()).return Task.CompletedTask;
- najprostsze ze wszystkich.Inną opcją, jeśli chcesz zachować prostą treść funkcji i nie pisać kodu obsługującego ją, jest po prostu pominięcie ostrzeżenia za pomocą #pragma:
Jeśli jest to wystarczająco powszechne, możesz umieścić instrukcję disable na początku pliku i pominąć przywracanie.
http://msdn.microsoft.com/en-us/library/441722ys(v=vs.110).aspx
źródło
Innym sposobem zachowania słowa kluczowego async (na wypadek, gdybyś chciał je zachować) jest użycie:
Po wypełnieniu metody możesz po prostu usunąć instrukcję. Używam tego często, zwłaszcza gdy metoda może na coś czekać, ale nie każda implementacja to robi.
źródło
Task.Run
wywołaniu.Task.CompletedTask
już nie istnieje.Task.FromResult
jest to lepsza odpowiedź. O to chodzi, jeśli są rzuci wyjątek, wydaje się inna odpowiedź nie wchodzą w grę w odniesieniu doTask.FromException
podejmowania tego nigdy rozwiązanie idealne. Zgodziłbyś się?Istnieje różnica między rozwiązaniami i mówiąc ściśle, powinieneś wiedzieć, w jaki sposób wywołujący wywoła metodę asynchroniczną, ale z domyślnym wzorcem użycia, który zakłada ".Wait ()" na wyniku metody - " return Task.CompletedTask " jest najlepszym rozwiązaniem.
Uwaga:
FromResult
nie można bezpośrednio porównać.Kod testu:
}
źródło
#pragma
jeden wydaje się ponosić koszty ogólne. Prawdopodobnie tyle samo narzutu, jakbyś zamiast zwrotuCompletedTask
utworzył i ukończył plikAsyncOperation
. Byłoby miło móc powiedzieć kompilatorowi, że można to pominąć, gdy metoda i tak działa synchronicznie.Task.CompletedTask
podobne jest podobne doTask.FromResult
? Ciekawe byłoby wiedzieć - spodziewam się, że FromResult byłby najbardziej analogiczny i nadal miałby najlepsze wyniki, gdyby trzeba było zwrócić wartość.Wiem, że to stary wątek i być może nie będzie to miało odpowiedniego efektu dla wszystkich zastosowań, ale poniższe informacje są tak bliskie, jak tylko mogę, aby móc po prostu wyrzucić NotImplementedException, gdy nie zaimplementowałem jeszcze metody, bez zmiany sygnatury metody. Jeśli jest to problematyczne, chętnie o tym dowiem się, ale to nie ma dla mnie znaczenia: i tak używam tego tylko podczas tworzenia, więc to, jak działa, nie jest aż tak ważne. Mimo wszystko z przyjemnością usłyszę o tym, dlaczego to zły pomysł, jeśli tak jest.
Oto typ, który dodałem, aby to umożliwić.
źródło
Podobnie jak aktualizacja odpowiedzi Stephena, nie musisz już pisać tej
TaskConstants
klasy, ponieważ istnieje nowa metoda pomocnicza:źródło
Jeśli już łączysz się z Reactive Extension, możesz również:
Reaktywne i async / await są niesamowite same w sobie i same w sobie, ale także dobrze grają razem.
Potrzebne obejmuje:
źródło
Może się to zdarzyć cs1998 poniżej.
Następnie możesz zreformować poniżej.
źródło
Możesz spróbować tego:
źródło
Spróbuj tego:
[System.Diagnostics.CodeAnalysis.SuppressMessage("Await.Warning", "CS1998:Await.Warning")]
Zobacz: https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.codeanalysis.suppressmessageattribute?view=netframework-4.7.2
źródło
Jeśli nie masz nic do czekania, zwróć Task.FromResult
źródło
Oto kilka alternatyw w zależności od podpisu metody.
źródło
źródło
Możesz usunąć słowo kluczowe async z metody i po prostu zwrócić Task;
źródło