Обратите внимание на вот этот вопрос: Зависает оператор `await` в оконном приложении / программа висит при вызове Task.Result или Wait
Там показана основная проблема таких вот вызовов GetResult(). И там же есть решение проблемы "но что делать если очень надо" через временный контекст синхронизации:
public Foo GetFoo()
{
using (var ctx = new QueueSynchronizationContext())
{
var task = GetFooAsync();
ctx.WaitFor(task);
return task.GetAwaiter().GetResult();
}
}
Но это решение подходит только для однопоточных контекстов синхронизации, при выполнении в неограниченном пуле потоков правильнее будет вызвать task.GetAwaiter().GetResult(); напрямую. В ограниченных же пулах потоков все еще сложнее - нельзя использовать QueueSynchronizationContext потому что он убьет параллельность - но нельзя и использовать блокирующее ожидание, потому что оно займет один поток.
Универсальным способом будет Task.Run(() => GetFooAsync()).GetAwaiter().GetResult(), но этот способ смотрится странно (и опять-таки, несет проблемы когда пул потоков ограничен).
Наверное, проще всего просто выбрать только один метод и использовать только его. Но если вы пишите библиотеку - возможно, правильнее всего будет написать алгоритм два раза, и в блокирующем варианте, и в асинхронном.
awaitесли просто вызывать разве он не синхронно будет выполняться? – Anatol Sep 15 '17 at 13:04Task<Foo>, а неFoo– Андрей NOP Sep 15 '17 at 13:18Task<T>– Sep 15 '17 at 13:30