Недавно я читал код, в котором используется много асинхронных методов, но иногда их нужно выполнять синхронно. Код делает:
Foo foo = GetFooAsync(...).GetAwaiter().GetResult();
Это то же самое, что
Foo foo = GetFooAsync(...).Result;
c#
async-await
Джей Базузи
источник
источник
GetResult
: «Этот тип и его члены предназначены для использования компилятором». Другой человек не должен его использовать.async
/await
в MVC)Ответы:
Довольно много. Однако есть одно небольшое отличие: в случае
Task
сбояGetResult()
будет просто сгенерировано исключение, вызванное напрямую, аTask.Result
сгенерируется файлAggregateException
. Однако какой смысл использовать любой из них, если он естьasync
? В 100 раз лучший вариант - использоватьawait
.Кроме того, вы не должны использовать
GetResult()
. Он предназначен только для использования компилятором, а не для вас. Но если вы не хотите раздражатьAggregateException
, используйте это.источник
async Task
модульные тесты и уже некоторое время поддерживают их .The 100x better option is to use await.
Я ненавижу подобные заявления, если бы я мог дать им пощечину, я бы сделалawait
это. Но, когда я пытаюсь получить асинхронный код для работы с не-асинхронным кодом , как то , что часто случается со мной много в Xamarin, я в конечном итоге того , чтобы использовать такие вещи , какContinueWith
много для того , чтобы сделать это не тупиковую интерфейс. Изменить: я знаю, что это старый, но это не облегчает мое разочарование, когда я ищу ответы, в которых говорится об отсутствии альтернатив для ситуаций, когда вы не можете просто использоватьawait
.Task.GetAwaiter().GetResult()
предпочтительнее,Task.Wait
иTask.Result
потому что он распространяет исключения, а не помещает их в файлAggregateException
. Однако все три метода могут привести к тупиковой ситуации и нехватке пула потоков. Их следует избегать в пользуasync/await
.Цитата ниже объясняет, почему,
Task.Wait
аTask.Result
не просто содержит поведение распространения исключенияTask.GetAwaiter().GetResult()
(из-за «очень высокой панели совместимости»).https://blogs.msdn.microsoft.com/pfxteam/2011/09/28/task-exception-handling-in-net-4-5/
http://blog.stephencleary.com/2014/12/a-tour-of-task-part-6-results.html
источник
Task.GetAwaiter().GetResult()
эквивалентноawait task
. Я предполагаю, что первый вариант используется, когда метод не может быть помеченasync
(например, конструктором). Это верно? Если да, то он совпадает с верхним ответом @ It'sNotALieTask.GetAwaiter().GetResult()
более эквивалентенTask.Wait
иTask.Result
(в том смысле, что все три будут синхронно блокироваться и иметь потенциал для взаимоблокировок), ноTask.GetAwaiter().GetResult()
имеет поведение распространения исключений задачи ожидания.https://github.com/aspnet/Security/issues/59
источник
Task.WhenAll(task1, task2).GetAwaiter().GetResult();
.Другое отличие заключается в том, что
async
функция возвращает толькоTask
вместоTask<T>
этого, вы не можете использоватьВ то время как
еще работает.
Я знаю, что пример кода в вопросе предназначен для данного случая
Task<T>
, однако вопрос задается в целом.источник
Result
сGetIntAsync()
которой возвращаетсяTask<int>
не толькоTask
. Предлагаю вам еще раз прочитать мой ответ.GetFooAsync(...).Result
внутри возвращающей функцииTask
. Теперь это имеет смысл, поскольку в C # нет void Properties (Task.Result
это свойство), но вы, конечно, можете вызвать метод void.Как уже упоминалось, если вы можете использовать
await
. Если вам нужно запускать код синхронно, как вы упомянули.GetAwaiter().GetResult()
,.Result
или.Wait()
существует риск возникновения взаимоблокировок, как многие сказали в комментариях / ответах. Поскольку большинству из нас нравятся одинарные лайнеры, вы можете использовать их для.Net 4.5<
Получение значения с помощью асинхронного метода:
var result = Task.Run(() => asyncGetValue()).Result;
Синхронный вызов асинхронного метода
Проблемы с взаимоблокировкой не возникнут из-за использования
Task.Run
.Источник:
https://stackoverflow.com/a/32429753/3850405
источник
источник: С # 7.0 в двух словах
источник