Я использовал только "GUI" доступ к базе данных в Delphi с компонентами DbExpress, но теперь я хотел бы выполнить один запрос в фоновом режиме. Я читал кое-где, что TSQLConnection не является потокобезопасным, и мне нужно создавать новое соединение для каждого потока. Я вижу, что в TSQLConnection есть CloneConnection, но справка утверждает, что новые соединения принадлежат исходному соединению.
So,
1) Как правильно выполнить TSQLQuery, расположенный на многопоточном модуле данных?
2) Могу ли я использовать TSQLConnection.CloneConnection? Должен ли я освободить клонированные соединения или оставить их нетронутыми после завершения потока?
Простой пример кода (или URL) был бы очень полезен.
Ответ 1 · рейтинг 5 · mghie
Это не относится к DbExpress (с которым у меня нет опыта), но лучшая идея для переноса некоторых функций в фоновый поток - сначала разработать их в основном потоке, отладить и, как только вы убедитесь, что все работает нормально, затем переместите его.
Что вы можете сделать, так это поместить все в TDataModule. Если модуль данных может работать сам по себе, не нуждаясь в других компонентах в других формах или модулях данных, и вы создаете его в фоновом потоке, то вы можете быть уверены, что все будет работать. Вам не нужно клонировать соединение, так как оно будет создано и уничтожено в том же потоке, где осуществляется весь доступ к базе данных.
Несколько важных советов по работе с базой данных с фоновыми потоками:
Обрабатывайте все исключения, так как необработанные исключения во вторичном потоке могут привести к сбою вашего приложения. Обработка исключений в объекте Application у вас не сработает.
Не обращайтесь ни к чему в потоке графического интерфейса. Это означает, что наиболее важно то, что TDataSource нельзя использовать, и нельзя использовать никакие элементы управления, чувствительные к данным.
Если используемые вами компоненты делают что-либо с SendMessage или PostMessage, вам придется создать стандартный цикл сообщений в фоновом потоке.
Если используемые вами компоненты что-либо делают с OLE, вызовите как OleInitialize (), так и OleUnitialize () в контексте фонового потока.
Если вы хотите облегчить себе жизнь, рассмотрите возможность использования OmniThreadLibrary или AsyncCalls. Какой из них зависит от того, как долго будут жить ваши фоновые подключения к базе данных и хотите ли вы их повторно использовать.