Asyn c задача блокируется, если задача извлекается первой - PullRequest
1 голос
/ 07 января 2020

Я использую Microsoft AsyncHelper ( source ) для вызова асинхронного c метода из синхронного контекста. Это работает просто отлично:

Result r = AsyncHelper.RunSync(async () => await SomeClass.SomeMethodAsync());

Однако, если я извлекаю Задачу и затем пытаюсь вместо этого запустить эту извлеченную задачу синхронно, я сталкиваюсь с тупиком .:

Task<Result> t = SomeClass.SomeMethodAsync();
Result r = AsyncHelper.RunSync(async () => await t);

Почему это случиться, и что можно сделать, чтобы запустить этот прогон?

1 Ответ

3 голосов
/ 11 января 2020

AsyncHelper.RunSync использует взлом пула потоков , чтобы гарантировать, что его делегат вызывается без контекста, что делает его безопасным для блокировки (при условии, что делегат безопасен для вызова в потоке пула потоков ). В вашем коде SomeMethodAsync выполняется в потоке пула потоков, поэтому любые await s не будут захватывать контекст .

что можно сделать, чтобы выполнить этот запуск ?

Хорошо, вы бы использовали первый пример кода вместо второго.

Если вы хотите иметь конструкцию, представляющую некоторый код для запуска, вам следует использовать делегат типа типа Func<Task<T>>. Например:

Func<Task<Result>> func = () => SomeClass.SomeMethodAsync();
Result r = AsyncHelper.RunSync(func);

При асинхронном коде Task<T> не представляет некоторый код для запуска; он представляет некоторый код, который уже запустил . Используйте Func<Task<T>> для представления кода для запуска.

...