TThread, Synchronize, VCL |
Прежде чем задать вопрос, смотрите FAQ.
Рекомендуем загрузить DRKB.
TThread, Synchronize, VCL |
sheka |
15.12.2011 18:44
Сообщение
#1
|
Я. Группа: Пользователи Сообщений: 809 Пол: Мужской Реальное имя: Саша Репутация: 11 |
Synchronize делает неактивным приложение, в то время как без него работает. Какие есть варианты решения этой проблемы? В form1.proc есть работа с VCL.
Код (Показать/Скрыть)
Где можно найти нормальное описание Synchronize? Сообщение отредактировано: sheka - 15.12.2011 18:48 |
IUnknown |
15.12.2011 19:45
Сообщение
#2
|
a.k.a. volvo877 Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: 627 |
Synchronize делает неактивным приложение, в то время как без него работает. А на кой тебе там вообще Synchronize? Тебе что, надо выполнять какие-то действия в контексте основного потока приложения? Нет, не надо (вот когда на форме будут обновляемые из потока контролы - тогда надо будет).Цитата form1.proc есть работа с VCL. Значит, обновление VCL-контролов (то что тебя сейчас есть - это не называется "работа с VCL", это можно делать и без синхронизации) выдели в отдельную процедуру, и вызывай ее через Synchronize. Чтоб она работала как можно быстрее. Зашла - обновила - вышла.Где можно найти нормальное описание Synchronize? Для начала - тебе сюда: Выучить наизусть, только потом работать с потоками (что-то сегодня я уже второй раз даю эту ссылку, все прямо так заинтересовались потоками... ) Сообщение отредактировано: IUnknown - 15.12.2011 19:48 |
sheka |
16.12.2011 18:06
Сообщение
#3
|
Я. Группа: Пользователи Сообщений: 809 Пол: Мужской Реальное имя: Саша Репутация: 11 |
Хорошее описание, спасибо.
Цитата Дело в том, что метод вызываемый посредством Synchronize() выполняется в контексте основного потока приложения. Это как раз и обеспечивает возможность использования нереентерабельных VCL-компонент. Некоторая информация должна обновляться из базы данных через достаточно короткий промежуток времени. Это обновление происходит ~2 секунды, что есть недопустимо долго. Работа с базой происходит через TIBQuery. Как реализовать данный момент? Как делаю я: В потоке создаю новый IBQuery2, считываю ним информацию из базы. Т.к. с IBQuery2 ничего не взаимодействует, то можно это сделать без использования Synchronize(). А как можно полученную IBQuery2 информацию "присвоить" тому, с которым работает вся остальная программа? |
IUnknown |
16.12.2011 18:51
Сообщение
#4
|
a.k.a. volvo877 Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: 627 |
Цитата А как можно полученную IBQuery2 информацию "присвоить" тому, с которым работает вся остальная программа? Никак. Чтобы получить данные, TIBQuery должна отработать заново, никакие Assign-ы или подобные вещи не могут перенести данные из одной <...>Query в другую.На самом деле, задача решается не просто, а очень просто: "вся остальная программа" работает не с T<...>Query, а с клиентским набором данных (который TClientDataSet). И пускай твой поток хоть полчаса получает информацию через TIBQuery. Вот когда он ее получил - ты тут же ее Synchonize-ируешь в TClientDataSet, и "все остальные" работают уже с новыми данными. |
sheka |
9.02.2012 17:08
Сообщение
#5
|
Я. Группа: Пользователи Сообщений: 809 Пол: Мужской Реальное имя: Саша Репутация: 11 |
Работает!
Но есть проблема: основная программа работает с некоторой базой. Поток работает с этой же базой. При одновременной работе основного и созданного потока (выполняются запросы одновременно и в основном и в созданном потоке) выдается вот такое сообщение: error.bmp ( 282.05 килобайт ) Кол-во скачиваний: 512 . (Таблицы используемые в запросах не совпадают). TIBDataBase - общий. TIBTransaction - 2 одинаковых: один на основной поток, один на созданный. Только для чтения с параметрами read read_committed rec_version nowait. Чего можно сделать? |
IUnknown |
9.02.2012 19:05
Сообщение
#6
|
a.k.a. volvo877 Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: 627 |
Цитата TIBDataBase - общий. Если версия IB ниже 7, то так делать нельзя (на форуме Embarcadero говорят, что начиная с 7 и более новых версий - можно, но я не пробовал), нужно свой TIBDatabase для каждого потока. |
sheka |
10.02.2012 11:06
Сообщение
#7
|
Я. Группа: Пользователи Сообщений: 809 Пол: Мужской Реальное имя: Саша Репутация: 11 |
Версия сервера firebird 1.5
IDE - delphi7, значит компоненты тоже 7й версии, значит как-то можно, осталось только найти как. Я правильно понимаю? (меня смущает вот эта картинка http://www.ibase.ru/devinfo/ibfbfeature1.gif т.к. delphi7 2002года и компоненты IB скорее всего родные, а IB7 появился позже). |
IUnknown |
10.02.2012 12:55
Сообщение
#8
|
a.k.a. volvo877 Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: 627 |
Цитата IDE - delphi7, значит компоненты тоже 7й версии, Неправда. С семеркой шла IB 5, последний апдейт был 5.1.28, так что ни разу не седьмой IB у тебя Если все-таки IB7 - то ходи сюда: Как выполнять запросы параллельно в приложении? Как работать с IB/FB из threads, и проверяй, коннект сетевой или локальный? Должен быть сетевой, при локальном будут сбои. |
Текстовая версия | 20.09.2024 6:09 |