У меня есть многопоточное приложение, использующее OmniThreadLibrary . Я неправильно использую OTL для открытия хранимых процедур ADO во вторичных потоках, который работает, если нет ошибки (и в основном даже тогда). К сожалению, в данном конкретном случае есть проблема.
Когда я открываю определенную форму, я получаю исключение в потоке «Должно быть хотя бы одно поле», копирующего набор данных в таблицу памяти kb, которую я обрабатываю и отправляю сообщение в поток мониторинга. Это сообщение приходит и успешно сохраняется в базе данных. Когда я закрываю эту форму, основной поток VCL зависает.
kbMemTable.LoadFromDataset(StoredProc, []); // throws
Приостановка приложения в отладчике и просмотр списка потоков, который показывает основной поток VCL:
"Blocked on critical section which is abandoned owned by Process 0"
Потоки OTL все еще находятся в рабочем состоянии и время истекло из пула потоков, поэтому кажется, что все работает, кроме основного потока. Я также использую компоненты DevExpress и Raise, которые имеют свои собственные потоки, но не называют их (и, похоже, не являются частью проблемы), что означает, что у меня 12 потоков, из которых только 5 идентифицируемы.
Я сильно подозреваю, что что-то в базе данных Delphi захватило этот критический раздел, а затем не удалось его освободить из-за исключения. Кажется, что в блоках исходного кода Delphi / базы данных, которые я использую напрямую, нет критических разделов, но, очевидно, что-то там есть.
Это включает слишком много исходного кода для включения, и мое тестовое приложение не отображает поведение.
Я прошу любые советы по отслеживанию этого.
Моя текущая мысль - переключаться на отладку dcu и точки останова при каждом критическом создании раздела, которое я могу найти, а затем посмотреть, что произойдет. Я мог бы решить проблему, которая вызывает первое исключение, но я обеспокоен тем, что какое-то другое исключение может иметь такой же эффект в той области, где было бы больно иметь дело. Поэтому я хотел бы сначала решить эту проблему.
Редактировать: критический раздел принадлежит потоку, который вызывает TADOStroredProc.ExecProc. Этот поток обычно завершает работу после обработки исключения, поэтому, если я не прыгну в отладчик быстро, поток выйдет из пула, прежде чем я его увижу, следовательно, ProcessID = 0 выше. Установка времени ожидания потока на 60 секунд вместо 10 секунд, по крайней мере, дает мне это.