В система имеются технологические задания. Они редактируются из пользовательского интерфейса, и так же изменяются контроллерами оборудования. Контроллер оборудования работает в отдельном потоке и обрабатывает очередь сообщений. Раньше один вид тех. заданий изменялся одним контроллером, и в то время, когда задание стояло на контроллере его изменять из гуи было запрещено, только читать. Проблема синхронизации решалась за счет того что все изменения происходили в одном потоке, и при изменении делался клон тех задания, менялся до нового согласованного состояния и только потом становился доступен читателям.
Теперь задание может стоять на двух контроллерах, работающих в разных потоках. Я решил что в таком случае перед началом изменений и чтений задание нужно лочить. Первое же что я получил, к моему огромному счастью, это классический дедлок.
Как исправить код в данной конкретной ситуации мне ясно. Но как избегать таких ситуаций в будущем не очень понятно.
Если получать все блокировки в вверху стека вызовов, через единый класс, это во первых, по сути сделает систему однопоточной, а во вторых в вверху стека не всегда ясно какие ещё блокировки понадобятся.
Делать короткие локи объекта тоже затруднительно, т.к. при переходе тех. задания в определенной статус нужно сохранить записи в другие таблицы и добавить в тех. задание ссылку на эти таблицы. Таким образом согласованное состояние получается после изменения статуса и исполнения кучи кода, записывающей другие сущности, где вполне могут быть локи.
Я конечно, догадываюсь, что все равно нужно стремиться к коротким локам, но тем не менее хочется услышать мнение форумчан.
Возможно порекомендуете мне какую нибудь книгу по подобным патернам.
Пишу на .net