Вопрос по multithreading – Показать заставку во время соединения с базой данных (это может занять много времени)

5

Я пытаюсь показать заставку, а не замораживать приложение, пока оно подключается к базе данных. Обычные соединения (с MSSQL через ADO) занимают около 300 мсек, и это не приводит к тому, что основной поток показывает «не отвечает» на окнах.

Однако в случае (a) сетевой ошибки или (b) ошибки конфигурации (недопустимое имя хоста / экземпляра сервера SQL) время ожидания составляет 60 секунд. Это не только делает приложение невосприимчивым, но практически невозможно показать какую-либо ошибку или сообщение, когда оно собирается зависнуть. Я мог бы выдать сообщение до того, как установил соединение, но действительно не существует решения, когда основной поток блокируется на 60 секунд.

Похоже, решение состоит в том, чтобы переместить соединение в фоновый поток. Это приводит к следующему коду:

  1. a TThread-class that makes the background connection and some SyncObj like a TEvent used to send a signal back to the main thread.

  2. A loop in the main thread with this code:

    BackgroundThread.StartConnecting;
    while not BackgroundThread.IsEventSignalled do begin
       Application.ProcessMessages; // keep message pump alive.
    end;
    // continue startup (reports error if db connection failed)
    

Это правильный путь? Мои колебания включают в себя следующие элементы вышеупомянутого решения:

О. Я буду вызывать Application.ProcessMessages, который я считаю крайне неприятным запахом кода (это может быть допустимым исключением из этого правила)

Б. Я внедряю потоки в запуск приложения, и я беспокоюсь о появлении ошибок.

Если у кого-либо есть эталонная реализация, которая, как известно, не содержит условий гонки, которая может установить фоновую связь с ADO и, как известно, является безопасным подходом, это было бы действительно полезно. В остальном общие советы или частичные примеры хороши.

Учитывая, что нормальное соединение занимает всего 300 мс, почему бы не изменить время ожидания (например, 1000 мс)? awmross
Как отобразить заставку из фоновой темы:stackoverflow.com/questions/388506/… Harriv
@David, или если вы не используете компоненты, учитывающие данные, перемещайте и запускайте базу данных в рабочих потоках. Это целесообразно, когда вы выполняете трудоемкие запросы и по какой-то причине хотите работать с пользовательским интерфейсом формы (не только блокировать пользователя с некоторой ожидающей анимацией). Эту модель я успешно использовал для инструмента, который периодически опрашивал базу данных, пока пользователь мог работать сthe rest приложения. Но должен сказать, что здесь будет подходящая форма рабочего потока. TLama
Эта проблема является одним из основных случаев использования для отображения пользовательского интерфейса из потока, отличного от основного потока графического интерфейса. David Heffernan
Чтобы создать форму без зависимости от VCL и подходит для потоков, см.Creating forms without using VCL или жеPeter Below's Threaded Splash Screen and Modal Dialogs. LU RD

Ваш Ответ

2   ответа
1

общения Window. Сначала я определяю обычное сообщение и обработчик сообщения в форме. Тогда, когда мне нужно сообщить основную Я использую функцию PostMessage для отправки уведомлений.

Небольшой учебникВот.

Вы также можете использовать библиотеку для многопоточности, например,OmniThreadLibrary.

Error: User Rate Limit Exceeded Warren P
Error: User Rate Limit Exceeded
4

что каждый поток должен использовать свое собственное ADO-соединение (т.е. вы не можете использовать объект соединения, созданный в другом потоке), единственная опция, о которой я могу думать, - это создать поток, который будет устанавливать соединение с базой данных, и , после того, как соединение установлено или истекло время ожидания, сообщите основному потоку о событии и закройте / уничтожьте соединение. Тем временем основной поток может отображать всплеск или прогресс, ожидая сообщения из этого потока. Таким образом, вы исключаете случай с неправильным паролем или недоступным хостом. Существует разумное предположение, что, если второй поток сможет подключиться, основной поток сможет подключиться сразу после этого.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Warren P
Error: User Rate Limit Exceeded

Похожие вопросы