Ответ 1
Да, вы должны изменить метод и удалить async/wait. Ключевое слово async
заставляет компилятор создать конечный автомат, который управляет ожиданием завершения задачи. Когда вы ждете еще одну такую функцию, вы по существу создаете две из этих состояний, которые не нужны. Гораздо лучше просто вернуть задачу из второй функции напрямую и позволить конечному потребителю задачи выполнить ожидание.
Лучший способ понять это - написать небольшую пробную программу и декомпилировать ее. Убедитесь, что ваш декомпилятор показывает вам все созданные компилятором вещи (которые некоторые скрывают по умолчанию), и вы сможете увидеть, что там происходит.
Вот быстрый пример, который я просто взбивал и использовал dotPeek для декомпиляции:
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");
}
Вы можете видеть конечный автомат в первом, о котором я говорил. Он собирается делать всю эту работу без причины, а затем конечный потребитель DoSomething()
собирается повторить ту же работу. Реально, вы действительно должны использовать только ключевое слово await
, если в методе, который должен быть запущен после, другой код, который возвращает задачу. Потому что этот код должен дождаться завершения, прежде чем он запустится.
Полный декомпилированный код здесь: http://pastebin.com/iJLAFdHZ