Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Пграмма "замерзает" пока TThread не завершится [WinXP]


Страницы:   1 2

гия ©   (2011-12-28 12:44:00) 

Здравствуйте
Пишу пограмму в Дельфи ХЕ под Windows XP в которой приходится выполнять долгие селекты.
Чтобы программа не "замерзала" пока селект не выполнится написал обработчик

procedure Button1Click(Sender: TObject);
begin
 with Query do begin
   Close;
   SQL.Clear;
   SQL.Add('SELECT .....');
   
   TMyThread.Create(Query);
   Application.ProcessMessages;
 end;
end;

TMyThread описан следующим образом:

unit uMyThread;

interface

uses
 Classes {$IFDEF MSWINDOWS} , Windows {$ENDIF}, Ora, Unit1;

type
 TMyThread = class(TThread)
 private
   FQuery: TOraQuery;
 protected
   procedure Execute; override;
 public
   constructor Create(Query: TOraQuery);
 end;

implementation

{ TMyThread }

constructor TMyThread.Create(Query: TOraQuery);
begin
 inherited Create(False);
 FQuery := Query;
 Priority := tpNormal;
 FreeOnTerminate:= True;
//  Resume;
 Execute;
end;

procedure TMyThread.Execute;
begin
 NameThreadForDebugging('MyThread');
 { Place thread code here }
 FQuery.Open;
end;

end.

Однако программа все равно "замерзает" пока селект не выполнится.
Что надо сделать что бы селект реально выполнялся бы в "background"-е, а прграмма продолжала бы выполнять другие вещи


OW   (2011-12-29 14:45:00) [1]


> что такое ThQ? и где надо его описать?

это твой класс.
ThQ ~ TMyКАКОЙТОClass = class(TThread)
что я писал - не под копи/паст, а как пример для подумать


MBo   (2011-12-29 13:56:00) [2]

Посмотри пример
http://delphi.about.com/od/kbthread/a/query_threading.htm

только учти, что строчка в Execute с ListBox.Items.Insert  - нехорошая, это нужно делать в методе, вызываемом через  Synchronize.

Остальное вроде сделано по-божески.


гия   (2011-12-29 13:32:00) [3]

аля так
ThQ := ThSQuery.Create(true);
ThQ.S := Session.ConnectString;
ThQ.SQL := S;
ThQ.Window := Handle;
ThQ.Msg := ESBD_COMPLETE_QUERY_SUBJECT;
ThQ.Resume;

что такое ThQ? и где надо его описать?


Сергей М.   (2011-12-28 17:47:00) [4]


> Если используются визуальные элементы, то через Synchronize


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


гия   (2011-12-28 17:41:00) [5]

Спасибо всем за оказанную помощь.
Сеглдня уже конец рабочего дня. Завтра с утра займусь


OW   (2011-12-28 17:33:00) [6]

поток сознания BEGIN

 ThSQuery = class(TThread)
наобъявить что надо
   FQ: TSmartQuery;
   FC: TOraSession;
   FS: string;
   FSQL: string;
   FHWND: Cardinal;
   FMsg: Cardinal;

написать удобных методов
procedure ThQuery.SetSQL(const Value: string);
begin
 if FC = nil then
 begin
    FC := TOraSession.Create(nil);
    FC.ConnectString := FS;
    FC.Options.Net := True;
    FC.Open;
 end;

 if FQ = nil then
begin
   FQ := TSmartQuery.Create(nil);
 FQ.Session := FC;
end;

 FQ.SQL.Text := Value;
end;

и юзать аля

 
ThQuery.SQL := 'select 1 from dual'
а тут и соединение и набор данных создастся закулисами
или, если было определено - не создаться.

   FHWND: Cardinal;
   FMsg: Cardinal;
инициализируется перед стартом потока, смысл - кому и о чем сообщить
аля так
 ThQ := ThSQuery.Create(true);
 ThQ.S := Session.ConnectString;
 ThQ.SQL := S;
 ThQ.Window := Handle;
 ThQ.Msg := ESBD_COMPLETE_QUERY_SUBJECT;
 ThQ.Resume;

а в потоке
procedure ThQuery.Execute;
begin

   if FQ <> nil then
   begin

       FQ.Open;
   end;
   SendMessage(FHWND, FMsg, 0, Integer(FQ)); //передаем указатель на набор данных
   FImBisy := False;

end;

Окно FHWND ожидает сообщения FMsg и знает, что оно указатель на результат запроса.
Там этот LParam и приводится к TSmartQuery

Form1 = class(TFORM)
   procedure CompleteQuery(var Msg: TMessage); message ESBD_COMPLETE_QUERY_SUBJECT;

procedure TfrmSubject.CompleteQuery(var Msg: TMessage);
   oqBase := TSmartQuery(Pointer(Msg.LParam));

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

поток сознания END
как-то так :)


MBo   (2011-12-28 17:14:00) [7]

>хоть текст запроса и пароль для коннекции можно передать из основного Thread-а?
Да

>как получить в таком случае в основном Thread-е результаты выполненного запроса?
Смотря что при этом делается. Если используются визуальные элементы, то через Synchronize


гия   (2011-12-28 16:46:00) [8]

и еще как получить в таком случае в основном Thread-е результаты выполненного запроса?


гия   (2011-12-28 16:16:00) [9]

Это сделаю. Но хоть текст запроса и пароль для коннекции можно передать из основного Thread-а?


Медвежонок Пятачок   (2011-12-28 16:06:00) [10]

создавать орасешшон внутри execute. и там же квери.


гия   (2011-12-28 15:54:00) [11]

г-н Сергей М.
Спасибо за подсказку
FQuery := Query; // конекшн создан в главном треде
Как поступить? Передать Thread-у указатель на TOraSession и присвоить значение уже в Thread-е?
И второе когда в место Execute написал Resume получаю сообщение об ошибке "Thread Error: The Handle is Invalid(6)"


Медвежонок Пятачок   (2011-12-28 15:46:00) [12]

а вот здесь тебя скорее всего ждет засада

это будет уже другая засада.
текущая засада:
Пграмма "замерзает" пока TThread не завершится


Сергей М.   (2011-12-28 15:36:00) [13]

constructor TMyThread.Create(Query: TOraQuery);
begin
inherited Create(True);
FQuery := Query; // а вот здесь тебя скорее всего ждет засада, если коннекшн, на который ссылается Query, создан в другом треде
FreeOnTerminate:= True;
 Resume;
end;


Медвежонок Пятачок   (2011-12-28 15:34:00) [14]

constructor TMyThread.Create(Query: TOraQuery);
begin
inherited Create(True);
FQuery := Query;
Priority := tpNormal;
FreeOnTerminate:= True;
Resume;
end;


гия   (2011-12-28 15:12:00) [15]

Госпада
Подскажите как правильно написать


Сергей М.   (2011-12-28 14:09:00) [16]


> реально-то все равно запускаются два экзекута


Ну это да.


> сначала во вторичном, затем в основном


Не факт. Хотя сути это конечно не меняет.


Медвежонок Пятачок   (2011-12-28 14:04:00) [17]

но реально-то все равно запускаются два экзекута.
сначала во вторичном, затем в основном.


Сергей М.   (2011-12-28 14:01:00) [18]


> Причем у него экзекут выполняется дважды
> второй раз - таки во вторичном


Это вряд ли.
Во вторичном экзекут наверняка обламывается на FQuery.Open


Медвежонок Пятачок   (2011-12-28 13:57:00) [19]

Причем у него экзекут выполняется дважды.
Один раз в главном потоке, а второй раз - таки во вторичном.

constructor TMyThread.Create(Query: TOraQuery);
begin
inherited Create( False);
...
//Resume;
Execute;
end;


Anatoly Podgoretsky   (2011-12-28 13:37:00) [20]

> Медвежонок Пятачок  (28.12.2011 13:17:02)  [2]

При этом управление вернется только после того, как закончится Execute


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо