Синхронизация по Async позволяет избежать взаимоблокировок и предотвратить реагирование пользовательского интерфейса
У нас есть библиотека, которая используется клиентами WPF и / или Winforms.
Мы'мы предоставили асинхронный метод, похожий на:
Task GetIntAsync()
Мы'Мы также (к сожалению) предоставили метод синхронной обертки:
int GetInt();
который по сути просто вызывает асинхронный метод и вызывает.Result
на свою задачу.
Мы недавно поняли при определенных обстоятельствах некоторый код вGetIntAsync
должен работать в главном потоке пользовательского интерфейса (необходимо использовать устаревший компонент COM, помеченный как "Не замужем" Модель многопоточности (то есть компонент должен работать в основном потоке STA, а не только в каком-либо потоке STA)
Так что проблема в том, что когдаGetInt()
вызывается в главном потоке, будеттупик поскольку
.Result
блокирует основной поток,код внутриGetIntAsync()
использованияDispatcher.Invoke
попытаться запустить основной поток.Синхронный метод уже используется, поэтому его удаление будет серьезным изменением. Так что вместо этого мымы решили использоватьWaitWithPumping в нашем синхронномGetInt()
метод, позволяющий вызывать основной поток для работы.
Это прекрасно работает, за исключением клиентов, которые используютGetInt()
из их кода пользовательского интерфейса. Ранее они ожидали, что с помощьюGetInt()
оставил бы их пользовательский интерфейс без ответа - то есть, если бы они позвонилиGetInt()
изнутри кнопки "s обработчик события щелчка, они ожидают, что никакие сообщения Windows не были обработаны, пока обработчик не вернулся. Теперь, когда сообщения прокачены, их интерфейсявляется отзывчивый и ту же кнопку можно нажать снова (и они, вероятно, некодировать их обработчик для повторного входа).
Если есть разумное решение, мыхотелось бы, чтобы наши клиенты не кодировали пользовательский интерфейс, реагирующий на вызовыGetInt
Вопрос:
Есть ли способ сделатьWaitWithPumping
что будет качатьВызов на главную " сообщения, но не прокачивать другие сообщения, связанные с пользовательским интерфейсом?Для наших целей было бы достаточно, если бы пользовательский интерфейс вел себя так, как будто в данный момент отображается модальное диалоговое окно, хотя и скрытое (то есть пользователь не может 'т доступ к другим окнам). Но из того, что я прочитал, вы не можете скрыть модальный диалог.Другие обходные пути, о которых вы можете подумать, будут оценены.