Delphi - Создание элемента управления, который выполняется в своем собственном процессе
ПРИВЕТ
У меня есть элемент управления, который обращается к базе данных, используя проприетарные наборы данных. База данных является старой базой данных ISAM.
Элемент управления использует фоновый поток для запроса базы данных с использованием проприетарных наборов данных.
Форма будет иметь несколько таких элементов управления, каждый из которых будет использовать свой собственный поток для доступа к данным, поскольку все они должны загружаться одновременно.
Собственные наборы данных обрабатывают параллелизм путем отображения VCL TForm, уведомляющего пользователя о том, что открываемая таблица заблокирована другим пользователем и что набор данных ожидает снятия блокировки.
Форма имеет кнопку отмены, которая позволяет пользователю отменить ожидание блокировки.
Эта проблема:
При использовании проприетарных наборов данных из потока приложение будет аварийно завершать работу, зависать или выдавать какую-либо ошибку, если форма ожидания блокировки будет отображаться. Я подозреваю, что это связано с тем, что VCL не является потокобезопасным.
Я решил проблему, синхронизировав Dataset.Open, однако он поддерживает основной поток до тех пор, пока не вернется dataset.open, что может занять значительное количество времени в зависимости от сложности запроса.
Я отобразил модальный индикатор выполнения, который позволяет пользователю узнать, что что-то происходит, но мне не нравится эта идея, поскольку пользователь будет сидеть в ожидании завершения индикатора выполнения.
Собственный код набора данных компилируется в основное приложение, то есть не хранится в отдельной DLL. На этой стадии процесса разработки нам не разрешено изменять работу блокировки или отображать форму или нет, поскольку мы слишком близки к выпуску.
В идеале я хотел бы, чтобы Dataset.open запускался в потоке элементов управления вместо использования основного потока, однако, похоже, это не сработает.
Может кто-нибудь еще предложить обходной путь? Пожалуйста.
2 ответа
Волокна не помогут вам ни на шаг, потому что они включены в Windows API исключительно для облегчения переноса старого кода, который был написан с учетом совместной многозадачности. Волокна - это, по сути, форма сопрограмм, все они выполняются в одном и том же процессе, имеют свое собственное пространство стека, и переключение между ними контролируется пользовательским кодом, а не ОС. Это означает, что переключение между ними может происходить только в безопасное время, поэтому проблем с синхронизацией нет. OTOH означает, что в одном потоке одновременно может работать только одно волокно, поэтому использование волокон с блокирующим кодом имеет те же характеристики, что и вызов блокирующего кода из одного потока - приложение перестает отвечать на запросы.
Вы можете использовать волокна вместе с несколькими потоками, но это может быть опасно и не дает никакой выгоды по сравнению с использованием только потоков.
Я успешно использовал волокна в приложениях VCL, но только для определенных целей. Забудьте о них, если вы хотите иметь дело с потенциально блокирующим кодом.
Что касается вашей проблемы - вы должны создать элемент управления, который используется только для целей отображения и который использует стандартные механизмы межпроцессного взаимодействия для обмена данными с другим процессом, который обращается к вашей базе данных.
COM-объекты могут работать в режиме вне процесса. Может быть, в Delphi их будет немного проще использовать, чем другие механизмы IPC.