У меня есть приложение Windows на платформе c # 3.5, которое работает с БД Oracle, расположенной на сервере.
Одна из форм приложения имеет восемь вкладок в верхней части. В области содержимого вкладки каждой вкладки есть поле со списком. В выпадающем списке отображается одинаковая информация в каждой форме. Когда пользователь изменяет значение поля со списком с помощью стрелок раскрывающегося списка или клавиатуры, тогда восемь областей с вкладками заполняются данными, полученными из Oracle.
Исходя из структуры существующей программы, каждый раз при изменении комбинированного списка открывается около 20 отдельных подключений к БД. Во-первых, около 8 вызывается для сохранения данных из разных вкладок в правильную таблицу. Содержимое каждой вкладки передается в класс БД для сохранения данных этой вкладки. Во-вторых, выполняется около 8 вызовов БД для загрузки вкладок из таблиц на основе комбинированного списка.
Чтобы уточнить, это все равно, что выбрать комбинированный список на любой вкладке, которая меняет модель автомобиля. Каждая вкладка будет выглядеть как «параметры интерьера», «параметры двигателя» и т. Д.
Затем выполняется несколько вызовов БД для блокировки высокоуровневой записи на основе идентификатора, чтобы никто другой не мог одновременно редактировать эту конкретную запись.
Процесс в целом довольно солидный. Время сохранения / загрузки очень быстрое. Я могу переключаться между двумя различными значениями комбинированного списка почти с мгновенным сохранением / загрузкой данных.
ТОГДА ПРОБЛЕМА
Если я вращаюсь назад и вперед достаточно быстро (что также сделали несколько пользователей), вся программа зависает. Никаких сбоев, просто зависает.
Повторяя это в среде отладки, я обнаружил, что она всегда останавливается на одной и той же строке кода (простое назначение набора записей (например, CarModelInterior.Notes = Convert.ToString (myReader [6]);)
Затем я обнаружил, что поток сборщика мусора (GC) работает в фоновом режиме, но каждый раз останавливается в одном и том же месте.
Введите установку мониторов памяти / производительности RED-Gate.
Я обнаружил, что чем быстрее и быстрее я переключал значения в поле со списком, тем быстрее заполнялась очередь GC Finalizer. В конечном счете, похоже, что тот же вызов SQL был в верхней части списка.
Введите мои предположения и догадки.
Я думаю, что либо слишком много открытых соединений и недостаточно быстрое завершение, либо где-то происходит блокировка.
Что я могу сказать, так это то, что ВСЕ (все безумные) из моих вызовов БД во всей программе используют оператор «ИСПОЛЬЗОВАНИЕ», поэтому все удаление выполняется автоматически. Кроме того, ВСЕ (как в случае «Да» я проверил все приложение), ВСЕ вызовы БД находятся в основном потоке. Следовательно, все 20 или около того вызовов DB, выполненных для каждого изменения значения в выпадающем списке, выполняются по порядку. Это исключило возможность блокировки, по крайней мере, до возможной проблемы с одним потоком.
Что я оставил? На данный момент, так много поисковиков, что я сдался и разместил здесь. Возможно ли, что очередь завершения не обрабатывается достаточно быстро? Есть еще идеи?