Ни GetAwaiter (). GetResult (), ни .Result не работали для меня, но Task.Run (await () => nameOfMethodTobeCalled ()). Результат работает. Я не поняла? - PullRequest
0 голосов
/ 23 января 2020

В моем приложении asp. net я вызывал какой-то асинхронный метод c одного пакета nuget, который я добавил в свое приложение. Теперь у меня есть метод syn c, в котором мне нужно вызвать asyn c метод .dll, который я добавил. Поэтому для этого я вызвал этот метод и для получения результата я использовал

var value = myDllClient.MyMethod (). GetAwaiter (). GetResult (); и
var value = myDllClient.MyMethod (). Result ;,

Но у меня ничего из этого не сработало, но поток перешел в бесконечный процесс. Я ничего не получал, поэтому я использовал

var value = Task.Run (asyn c () => await myDllClient.MyMethod ()). Результат;

на удивление нормально работает. Я не знаю, как это работает? Может ли кто-нибудь помочь мне понять эту тайну?

Заранее спасибо

Ответы [ 2 ]

2 голосов
/ 24 января 2020

Итак, для этого я вызвал этот метод, и для получения результата я использовал

Лучшее решение - использовать await и , позволяющие асинхронности естественным образом расти в коде. база . Если у вас есть для выполнения syn c -over-asyn c, тогда прямая блокировка может привести к тупикам .

await захватывает контекст по умолчанию , и в вашем случае await внутри MyMethod захватывает ASP. NET контекст запроса , существовавший до до Core версии ASP. NET. Затем вызывающий код блокирует поток в этом контексте запроса, вызывая GetResult() / Result. Позже, когда await готов продолжить, он планирует остаток от MyMethod в этом контексте. Но он никогда не будет запущен, поскольку в этом контексте есть поток, заблокированный в ожидании завершения MyMethod.

Причина, по которой Task.Run не блокируется, заключается в том, что MyMethod использует контекст пула потоков вместо ASP. NET контекст запроса. Это "взлом пула потоков" подход к выполнению syn c -over-asyn c. Однако Task.Run не рекомендуется для ASP. NET; если возможно, измените код на await.

1 голос
/ 24 января 2020

Оборачивая ваш вызов в Task.Run, вы изолируете этот код от ASP. NET * SynchronizationContext и, следовательно, ваш код не заходит в тупик.

...