IPB
ЛогинПароль:

> ВНИМАНИЕ!

Прежде чем задать вопрос, смотрите 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
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 15.12.2011 19:45
Сообщение #2


a.k.a. volvo877
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской

Репутация: -  627  +


Цитата(sheka @ 15.12.2011 17:44) *
Synchronize делает неактивным приложение, в то время как без него работает.
А на кой тебе там вообще Synchronize? Тебе что, надо выполнять какие-то действия в контексте основного потока приложения? Нет, не надо (вот когда на форме будут обновляемые из потока контролы - тогда надо будет).

Цитата
form1.proc есть работа с VCL.
Значит, обновление VCL-контролов (то что тебя сейчас есть - это не называется "работа с VCL", это можно делать и без синхронизации) выдели в отдельную процедуру, и вызывай ее через Synchronize. Чтоб она работала как можно быстрее. Зашла - обновила - вышла.

Цитата(sheka @ 15.12.2011 17:44) *
Где можно найти нормальное описание Synchronize?
Для начала - тебе сюда: Выучить наизусть, только потом работать с потоками

(что-то сегодня я уже второй раз даю эту ссылку, все прямо так заинтересовались потоками... smile.gif )

Сообщение отредактировано: IUnknown - 15.12.2011 19:48
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
sheka
сообщение 16.12.2011 18:06
Сообщение #3


Я.
****

Группа: Пользователи
Сообщений: 809
Пол: Мужской
Реальное имя: Саша

Репутация: -  11  +


Хорошее описание, спасибо.
Цитата
Дело в том, что метод вызываемый посредством Synchronize() выполняется в контексте основного потока приложения. Это как раз и обеспечивает возможность использования нереентерабельных VCL-компонент.

Некоторая информация должна обновляться из базы данных через достаточно короткий промежуток времени. Это обновление происходит ~2 секунды, что есть недопустимо долго. Работа с базой происходит через TIBQuery.
Как реализовать данный момент?
Как делаю я:
В потоке создаю новый IBQuery2, считываю ним информацию из базы. Т.к. с IBQuery2 ничего не взаимодействует, то можно это сделать без использования Synchronize(). А как можно полученную IBQuery2 информацию "присвоить" тому, с которым работает вся остальная программа?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 16.12.2011 18:51
Сообщение #4


a.k.a. volvo877
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской

Репутация: -  627  +


Цитата
А как можно полученную IBQuery2 информацию "присвоить" тому, с которым работает вся остальная программа?
Никак. Чтобы получить данные, TIBQuery должна отработать заново, никакие Assign-ы или подобные вещи не могут перенести данные из одной <...>Query в другую.

На самом деле, задача решается не просто, а очень просто: "вся остальная программа" работает не с T<...>Query, а с клиентским набором данных (который TClientDataSet). И пускай твой поток хоть полчаса получает информацию через TIBQuery. Вот когда он ее получил - ты тут же ее Synchonize-ируешь в TClientDataSet, и "все остальные" работают уже с новыми данными.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
sheka
сообщение 9.02.2012 17:08
Сообщение #5


Я.
****

Группа: Пользователи
Сообщений: 809
Пол: Мужской
Реальное имя: Саша

Репутация: -  11  +


Работает!
Но есть проблема: основная программа работает с некоторой базой. Поток работает с этой же базой. При одновременной работе основного и созданного потока (выполняются запросы одновременно и в основном и в созданном потоке) выдается вот такое сообщение: Прикрепленный файл  error.bmp ( 282.05 килобайт ) Кол-во скачиваний: 455
. (Таблицы используемые в запросах не совпадают).
TIBDataBase - общий.
TIBTransaction - 2 одинаковых: один на основной поток, один на созданный. Только для чтения с параметрами read read_committed rec_version nowait.
Чего можно сделать?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 9.02.2012 19:05
Сообщение #6


a.k.a. volvo877
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской

Репутация: -  627  +


Цитата
TIBDataBase - общий.
Если версия IB ниже 7, то так делать нельзя (на форуме Embarcadero говорят, что начиная с 7 и более новых версий - можно, но я не пробовал), нужно свой TIBDatabase для каждого потока.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
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 появился позже).
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 10.02.2012 12:55
Сообщение #8


a.k.a. volvo877
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской

Репутация: -  627  +


Цитата
IDE - delphi7, значит компоненты тоже 7й версии,
Неправда. С семеркой шла IB 5, последний апдейт был 5.1.28, так что ни разу не седьмой IB у тебя smile.gif

Если все-таки IB7 - то ходи сюда: Как выполнять запросы параллельно в приложении? Как работать с IB/FB из threads, и проверяй, коннект сетевой или локальный? Должен быть сетевой, при локальном будут сбои.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 28.03.2024 23:25
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"