Не можете использовать команду расширения для вызова asyn c из синхронного режима? - PullRequest
0 голосов
/ 21 января 2020

Я обнаружил метод расширения, который мы использовали в нашей базе кода для вызова асинхронных c методов из синхронного кода, не полностью выполняет то, что я ожидал. Код следует указаниям по MSDN: https://docs.microsoft.com/en-us/archive/msdn-magazine/2015/july/async-programming-brownfield-async-development

public static T AsyncSafeWait<T>(this Task<T> task)
{
    T retVal = default;
    Task.Run(async () => retVal = await task).Wait();
    return retVal;
}

Это позволяет просто и интуитивно понятно:

var response = PostAsync(...).AsyncSafeAwait();

Однако, поскольку это расширение метод, вызов asyn c запускается и, таким образом, текущий контекст захватывается перед передачей Task методу расширения. Это вызывает проблемы во многих синхронных случаях, наиболее очевидным из которых является поток пользовательского интерфейса, где он вызывает взаимоблокировку. По сути, метод расширения становится не более полезным, чем .Result, что является плохой практикой по тем же и другим причинам.

Мой вопрос: есть ли способ обернуть этот уродливый де-асин c Task.Run код, поэтому мне не нужно копировать-вставлять Task.Run(async () => retVal = await TheRealAsyncCall(...)).Wait(); везде?

Спасибо!

1 Ответ

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

есть ли способ обернуть этот уродливый де-асин c Task.Run код

Нет. Любой метод расширения Task запускается на одном экземпляре Task, и метод должен уже быть вызван к тому времени, когда код имеет Task.

после того, как ваш код имеет Task, слишком поздно менять способ вызова метода. Лучшее решение - передать делегата. Или просто полностью удалите метод AsyncSafeWait, а затем начните очистку.

...