Предотвращение тупика при вызове метода асинхронного использования без использования
Мне нужно вызвать метод, возвращающий Task
из
public override void OnActionExecuting(ActionExecutingContext filterContext)
Это не позволит мне сделать этот метод асинхронным, он выдает следующие
Асинхронный модуль или обработчик завершен во время асинхронного операция все еще ожидала.
и при вызове
entityStorage.GetCurrentUser().Result
Я зашел в тупик. Как я могу избежать этого?
Я играю с ним, придумывая такие вещи, как
entityStorage.GetCurrentUser().Result.ConfigureAwait(false).GetAwaiter().GetResult();
Но это не работает. Как мне это сделать? Моему решению придется работать с ASP.NET 4 и Async Targetting Pack, я не могу использовать ASP.NET 4.5 при развертывании на Azure.
Ответы
Ответ 1
Так как ожидание - это просто синтаксический сахар для компилятора, переписывающего продолжение для вас, самым "прямым" путем было бы взять любой код, который будет следовать вашему ожиданию и сделать его продолжением с вызовом.
Итак, что-то вроде:
entityStorage.GetCurrentUser().ContinueWith(t =>
{
// do your other stuff here
});
Ответ 2
Причина тупика объясняется здесь. Короче говоря, не блокируйте код async
. Вы должны использовать ConfigureAwait(false)
в вашей библиотеке async
code и await
результаты (не использовать Result
или Wait
).
Обновление: Пожалуйста, проголосовать здесь для команды MVC, чтобы добавить поддержку фильтров действий async
.
Ответ 3
Если вы ДОЛЖНЫ конвертировать asynch для синхронизации.
public User GetCurrentUserSynch()
{
return Task.Run(() =>
{
var asyncResult = entityStorage.GetCurrentUser();
while (!asyncResult.IsCompleted)
{
Application.Current.TryFindResource(new object()); // This is for WPF but you can do some other nonsense action of your choosing
}
return asyncResult.Result;
}).Result;
}
В противном случае используйте ответ @Stephen.