Task.GetAwaiter().GetResult()
є кращим Task.Wait
і Task.Result
тому, що він поширює винятки, а не загортає їх у AggregateException
. Однак усі три методи спричиняють можливі проблеми з голодуванням та голодуванням в пулі. Їх слід уникати на користь async/await
.
Цитата нижче пояснює, чому Task.Wait
та Task.Result
не просто містять поведінку щодо поширення винятків Task.GetAwaiter().GetResult()
(через "дуже високу смугу сумісності").
Як я вже згадував раніше, у нас дуже високий рівень сумісності, і тому ми уникали порушень змін. Як така, Task.Wait
зберігає свою первісну поведінку завжди обгортаючи. Однак ви можете опинитися в деяких складних ситуаціях, коли ви хочете, щоб поведінка була аналогічною синхронному блокуванню, використовуваному Task.Wait
, але де ви хочете, щоб оригінальний виняток розповсюджувався розпакованим, а не містився в AggregateException
. Для цього можна безпосередньо націлити на офіціанта Завдання. Коли ви пишете " await task;
", компілятор переводить це у використання Task.GetAwaiter()
методу, який повертає екземпляр, який має GetResult()
метод. При використанні у несправній задачі GetResult()
поширюватиметься вихідний виняток (саме так " await task;
" отримує свою поведінку). Таким чином, ви можете використовувати "task.GetAwaiter().GetResult()
"Якщо ви хочете безпосередньо використати цю логіку поширення.
https://blogs.msdn.microsoft.com/pfxteam/2011/09/28/task-exception-handling-in-net-4-5/
" GetResult
" Насправді означає "перевірити завдання на наявність помилок"
Взагалі я намагаюся уникати синхронного блокування асинхронного завдання. Однак є кілька ситуацій, коли я порушую ці настанови. У тих рідкісних умовах мій кращий метод полягає в GetAwaiter().GetResult()
тому, що він зберігає винятки із завдання, а не загортати їх у AggregateException
.
http://blog.stephencleary.com/2014/12/a-tour-of-task-part-6-results.html
GetResult
: "Цей тип та його члени призначені для використання компілятором." Інша людина не повинна ним користуватися.