Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2012.04.22;
Скачать: [xml.tar.bz2];

Вниз

Пграмма "замерзает" пока TThread не завершится   Найти похожие ветки 

 
гия   (2011-12-28 12:44) [0]

Здравствуйте
Пишу пограмму в Дельфи ХЕ под 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"-е, а прграмма продолжала бы выполнять другие вещи


 
RWolf ©   (2011-12-28 13:11) [1]

надо правильно использовать класс TThread.
пример есть в Demos\Threads.


 
Медвежонок Пятачок ©   (2011-12-28 13:17) [2]

твой экзекут вызван из главного потока а значит и выполняется в нем.
а это значит что сам поток теперь нахрен не нужен.
его можно просто выкинуть, и просто вызывать FQuery.Open из главного


 
Anatoly Podgoretsky ©   (2011-12-28 13:37) [3]

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

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


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

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

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


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


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


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


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

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


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


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


Ну это да.


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


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


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

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


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

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


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

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


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

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

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


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

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


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

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


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

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


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

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


 
MBo ©   (2011-12-28 17:14) [16]

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

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


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

поток сознания 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
как-то так :)


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

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


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


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


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


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

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

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


 
MBo ©   (2011-12-29 13:56) [21]

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

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

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


 
OW ©   (2011-12-29 14:45) [22]


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

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



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2012.04.22;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.002 c
15-1323981002
Юрий
2011-12-16 00:30
2012.04.22
С днем рождения ! 16 декабря 2011 пятница


2-1324926935
Kilowatt
2011-12-26 23:15
2012.04.22
Не получается загружать картинки формата PNG в ImageList. D 2009


2-1325185725
Plast
2011-12-29 23:08
2012.04.22
Конвертировать String в GUID?


2-1325071675
Plast
2011-12-28 15:27
2012.04.22
Програмно узнать все интерфейсы объекта.


2-1325179999
Антоха_М
2011-12-29 21:33
2012.04.22
Печать чеков из приложения Delphi





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский