procedure TForm1.proc; var i: Integer; d: Double; begin for i := 0 to MaxInt div 2 do d := d; end;
procedure TForm1.btn1Click(Sender: TObject); begin btn1.Enabled:=False; PT:=TMyThread.Create(false); end;
procedure TForm1.btn2Click(Sender: TObject); begin if Assigned(pt) then Self.btn2.Caption := IntToStr(Byte(PT.terminated)); end;
procedure TMyThread.Execute; begin Synchronize (MyDo); Form1.btn1.Enabled:=True; Terminate; end;
procedure TMyThread.MyDo; begin form1.proc; end;
end.
Где можно найти нормальное описание 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=0entry372043
(что-то сегодня я уже второй раз даю эту ссылку, все прямо так заинтересовались потоками... )
Автор: 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 у тебя
Если все-таки IB7 - то ходи сюда: http://www.ibase.ru/ibfaq.htm#threads, и проверяй, коннект сетевой или локальный? Должен быть сетевой, при локальном будут сбои.