Tak, należy zmienić metodę i usunąć asynchroniczne/czekające. Słowo kluczowe async
powoduje, że kompilator tworzy komputer stanu, który zarządza "oczekiwaniem" na zakończenie zadania. Kiedy czekasz na inną taką funkcję, zasadniczo tworzysz dwie z tych maszyn stanów, które są niepotrzebne. Znacznie lepiej jest po prostu zwrócić zadanie z drugiej funkcji bezpośrednio i pozwolić użytkownikowi końcowemu na wykonanie czekania.
Najlepszym sposobem zrozumienia tego jest napisanie małego przykładowego programu i jego dekompilacja. Upewnij się, że twój dekompilator pokazuje ci wszystkie rzeczy generowane przez kompilator (niektóre ukrywają się domyślnie) i będziesz mógł zobaczyć, co się tam dzieje.
Oto krótki przykład Właśnie bita i używane dotPeek dekompilować:
public Task<string> DoSomething()
{
Class1.\u003CDoSomething\u003Ed__0 stateMachine;
stateMachine.\u003C\u003E4__this = this;
stateMachine.\u003C\u003Et__builder = AsyncTaskMethodBuilder<string>.Create();
stateMachine.\u003C\u003E1__state = -1;
stateMachine.\u003C\u003Et__builder.Start<Class1.\u003CDoSomething\u003Ed__0>(ref stateMachine);
return stateMachine.\u003C\u003Et__builder.Task;
}
private Task<string> DoSomethingElse()
{
return Task.FromResult<string>("test");
}
Można zobaczyć maszynę stanów w pierwszym, że miał na myśli. Wykona całą tę pracę oczekując bez powodu, a wtedy końcowy konsument z DoSomething()
powtórzy tę samą pracę. Realistycznie powinieneś używać tylko słowa kluczowego await
, gdy jest inny kod w metodzie, która musi być uruchomiona po kodzie, który zwraca zadanie. Ponieważ ten kod musi czekać, aby zakończyć przed uruchomieniem.
Pełna decompiled kod tutaj: http://pastebin.com/iJLAFdHZ
No. Nie trzeba w tym celu metod, chyba że chcesz używać wartości zwracanej zadania w samej metody. –
[Pokrewne pytanie] (http://stackoverflow.com/questions/19098143/what-is-the-pose-of-return-await-in-c) i [koszt asynchronizacji czekają] (https: // msdn. microsoft.com/en-us/magazine/hh456402.aspx) –