Я пишу приложение для WPF в шаблоне MVC. Цель приложения - отобразить некоторые данные в базе данных, и эти данные обновляются асинхронно.Threadsafe observer pattern
Я подумываю о том, как проектировать архитектуру, чтобы она была потокобезопасной. В частности:
- Каждая страница (или ее модель) должна быть в состоянии подписаться и отказаться от подписки на услугу, которая обновляет базу данных.
- Служба, обновляющая базу данных, информирует всех подписчиков о появлении новых данных и обновлении их представлений.
Очевидно, что страница, которая только что закрывается, должна отказаться от подписки на услугу, а страница, которая только что появляется, должна (или может) подписаться.
я мог бы поставить подписку внутри критической секции, а также передачи о новых данных, но представьте себе следующий сценарий (стр ~ = его ViewModel, это не имеет большого значения, здесь):
- служба входит критический раздел для передачи информации о новых данных (в отдельном потоке)
- Страница пытается войти в критический раздел, чтобы отказаться от подписки (в основном потоке)
- Служба сообщает страницу о новых данных (в отдельной теме).
- Страница заполняет поля и вызывает событие PropertyChange (в отдельном потоке).
- Событие PropertyChange сортируется по основному потоку. Который ждет критический раздел.
И это похоже на тупик для меня.
Как я могу безопасно спроектировать эту архитектуру, чтобы избежать таких взаимоблокировок? Возможно, страницы никогда не должны отписываться? Или есть другой способ защитить потоки, чтобы они не зашли в тупик?
Это выглядит действительно странно, как подход. В частности, как «служба» знает, что некоторые данные являются новыми? это потому, что он только что был представлен вашим собственным приложением? – zaitsman
Почему главный поток должен получить критический раздел? (в последней точке пули)? Также, почему вы стреляете в события, удерживая замки ?, это очень вероятно приведет к блокировкам! Также будет полезен некоторый код, демонстрирующий проблему. –
Вообще говоря, вы не можете иметь тупик с ресурсом _one_. Чтобы иметь тупик, у вас должно быть 2 или более охраняемых ресурсов и закрытый цикл блокировки -> заблокированный график. Вы используете термин «критический раздел» (что не является проблемой), но вы должны очистить, какие функции охраны/мьютекса/семафора/etc вы используете, у вас есть 2 или более или только один. Я предполагаю, что после выполнения части кода отмены подписки (в основном потоке пользовательского интерфейса) маршаллированная (поставленная в очередь) PropertyChange будет работать без блокировки. Конечно, это может вызвать проблемы, если структуры данных недействительны, однако это не имеет ничего общего с тупиком. –