Переключатель потоков в асинхронной основной C# 7.1

Я столкнулся с проблемой с основной функцией асинхронного C# 7.1.

Вот ссылка на github для примера проекта, чтобы продемонстрировать проблему: https://github.com/xorpherion/CSharpAsyncMainProblem

Код используется как часть игрового цикла. Как вы видите, основная сигнатура использует асинхронный режим, поэтому за кулисами создается контекст синхронизации.

Класс Timedloop является своего рода таймером, который пытается запланировать событие (OnTick), когда текущее время превышает лимит. Есть 3 метода для запуска события: SpinLoop, WaitLoopAsync и WaitLoop. SpinLoop и WaitLoop ведут себя как ожидалось (однопоточное планирование OnTick). Проблема заключается в WaitLoopAsync. То, что я ожидаю здесь, это также остаться в текущем потоке, так как.ConfigureAwait не установлен в "ложь". Но когда вы запустите код, вы увидите на консоли сообщения об изменении идентификатора потока. Это не происходит с другими типами цикла.

Мой вопрос здесь: почему продолжение не запланировано в той же теме?

Я использую это на ядре.net 2.1.

1 ответ

Решение

Как вы видите, основная сигнатура использует асинхронный режим, поэтому за кулисами создается контекст синхронизации.

Нет, это не так. Ожидание задачи (по умолчанию) будет использовать контекст синхронизации, если он запущен в одном, но не будет автоматически создавать его. Консольное приложение обычно не имеет контекста синхронизации, поэтому продолжения выполняются в потоке пула потоков.

Если вы хотите, чтобы консольное приложение использовало контекст синхронизации, вам нужно создать его самостоятельно. AsyncEx проект Стивена Клири содержит реализацию; см. этот ответ о переполнении стека для более подробной информации.

Другие вопросы по тегам