Давайте пройдемся по тому, что вы делаете, и скажем точно, почему это неправильно.
var value = this.SomeFunction(...);
Прежде всего: используйте var
, когда тип либо чистый, либо неважный. Тип здесь неясен, и он важен .
Второе: имя функции, асинхронные с суффиксом Async
.
Давайте исправим ваш пример.Это все еще неправильно, но теперь это более ясно:
Task<Toast> toastTask = this.StartToasterAsync();
Toast toast = await Task.FromResult(toastTask.Result);
Этот рабочий процесс совершенно неверен. Давайте переведем его на английский.Вот мой список дел на сегодня:
- Положите немного хлеба в тостер.
- Пока хлеб поджаривается, я мог бы выполнять другую работу, но вместо этого смотретьпока тостер ничего не делает, пока он не будет сделан .
- Получите тост из тостера и создайте новый список дел.
- Новый список дел: Получить кусок тоста, который я сейчас держу.
- Выполнить этот список дел.Пока я жду, пока список дел завершится, иди делай другую работу, , но список дел всегда уже завершен, потому что задача состоит в том, чтобы получить результат, который я уже получил .Так что не занимайся другой работой.Просто проверьте, что да, я на самом деле держу кусок тоста, о котором я только что написал список дел.
- Теперь у меня есть кусок тоста.
Этот рабочий процессбезумный способ сделать тост.Это работает - в конце вы получите кусочек тоста - но ни один разумный человек не сделает этого, и вам не следует писать эквивалентную компьютерную программу:
- Это «асинхронный»рабочий процесс, в котором все возможные асинхронные преимущества были удалены .
- Первый шаг - ожидание появления тостера - синхронно ожидался.
- Второй шаг - асинхронное ожидание задачи, которая уже выполнена, никогда не бывает асинхронным!
Никогда никогда не пишите асинхронный код таким образом.
Правильный рабочий процесс для изготовления тоста:
- Положите хлеб в тостер и начинайте его поджаривать.
- Выполняйте другие работы, пока тост не лопнет.
- Принесите тост.
И, как мы и ожидали, правильный способ написания вашей программы намного проще:
Task<Toast> toastTask = this.StartToasterAsync(...);
Toast toast = await toastTask;
Или даже лучше:
Toast toast = await this.StartToasterAsync(...);
Вы новичок в этом, и вы не усвоили значения различных операций в асинхронных рабочих процессах.Операции в вашей маленькой программе:
.Result
означает, что перестает быть асинхронным и ничего не делает, пока не станет доступен результат .Обратите внимание, что это может вызвать взаимные блокировки .Вы останавливаете поток, пока не станет доступен результат; что если вы остановите поток, который собирался дать результат в будущем ?Представьте, например, что мы сделали список дел: «(1) Заказать коробку конфет из Интернета. (2) Ничего не делать, пока шоколад не прибудет. (3) Достать шоколад из почтового ящика».Этот рабочий процесс не завершается, поскольку существует синхронное ожидание результата, который требует от вас выполнения работы в будущем . await
означает , этот рабочий процесс не может продолжаться до тех пор, пока не будет получендоступно, так что асинхронно ждите его .Выйдите и найдите другую работу, и когда результат будет доступен, мы начнем снова здесь.
Обратите внимание, что оба они означают одно и то же, в этом оба являются точкамив рабочем процессе, где рабочий процесс не продолжается, пока не станет доступен результат .Но они совершенно разные в том смысле, что Result
является синхронным ожиданием, а await
является асинхронным ожиданием. Убедитесь, что вы понимаете это .Это самый фундаментальный момент, который вы должны понять.
И, наконец,
FromResult
означает , кому-то нужна задача, но у меня уже есть результат этой задачи, поэтому сделайте задачу, которая уже выполнена .Когда он await
ed или Result
вызывается для него, в любом случае, он немедленно возвращает результат.
Это необычно для вызова FromResult
.Если вы находитесь в асинхронном рабочем процессе, обычно вы просто return result;
сообщаете, что задача выполнена.