Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Delphi _ TThread, Synchronize, VCL

Автор: sheka 15.12.2011 18:44

Synchronize делает неактивным приложение, в то время как без него работает. Какие есть варианты решения этой проблемы? В form1.proc есть работа с VCL.

Код (Показать/Скрыть)

Где можно найти нормальное описание Synchronize?

Автор: IUnknown 15.12.2011 19:45

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

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

Цитата(sheka @ 15.12.2011 17:44) *
Где можно найти нормальное описание Synchronize?
Для начала - тебе сюда: http://forum.sources.ru/index.php?showtopic=55726&st=0&#entry372043

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

Автор: sheka 16.12.2011 18:06

Хорошее описание, спасибо.

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

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

Автор: IUnknown 16.12.2011 18:51

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

На самом деле, задача решается не просто, а очень просто: "вся остальная программа" работает не с T<...>Query, а с клиентским набором данных (который TClientDataSet). И пускай твой поток хоть полчаса получает информацию через TIBQuery. Вот когда он ее получил - ты тут же ее Synchonize-ируешь в TClientDataSet, и "все остальные" работают уже с новыми данными.

Автор: sheka 9.02.2012 17:08

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

Автор: IUnknown 9.02.2012 19:05

Цитата
TIBDataBase - общий.
Если версия IB ниже 7, то так делать нельзя (на форуме Embarcadero говорят, что начиная с 7 и более новых версий - можно, но я не пробовал), нужно свой TIBDatabase для каждого потока.

Автор: sheka 10.02.2012 11:06

Версия сервера firebird 1.5
IDE - delphi7, значит компоненты тоже 7й версии, значит как-то можно, осталось только найти как. Я правильно понимаю?
(меня смущает вот эта картинка http://www.ibase.ru/devinfo/ibfbfeature1.gif т.к. delphi7 2002года и компоненты IB скорее всего родные, а IB7 появился позже).

Автор: IUnknown 10.02.2012 12:55

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

Если все-таки IB7 - то ходи сюда: http://www.ibase.ru/ibfaq.htm#threads, и проверяй, коннект сетевой или локальный? Должен быть сетевой, при локальном будут сбои.