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

Вниз

Подождать окончяние THread-a   Найти похожие ветки 

 
alles ©   (2006-08-03 14:40) [0]

Здраствуйте.
Я с THread-ами не так хорошо знаком и попрошу у Вас помощь.
На клиенте вызывается прцедура которая находится на сервере, это занимает много времени. Чтобы юзеру показать что программа не умерла, создал форму (FrmWait) на которой находится TImage где по таймеру меняются 3 картинки (ролик маленкий).
Делаю так:
GlobalsVar.UserId:=0; //integer variable
try
          Application.CreateForm(TFrmWait, FrmWait);
          FrmWait.Show;
{В этом THread-e получяем GlobalsVar.UserId}
          ThreadConnect := TConnectThread.Create;
{как ожидать тут окончяние ThreadConnect-а и потом продолжить с if-ом ?}
          if (GlobalsVar.UserId= 0) then
          ShowMessage("Error");
finally
             FrmWait.Release; FrmWait:=nil;
end;

при деббугер-е запускает TConnectThread и сразу программа пытается проверить GlobalsVar.UserId на 0 которая еще небыло присвоенно в TConnectThread.

Спасибо


 
Сергей М. ©   (2006-08-03 14:42) [1]

метод TThread.WaitFor на то существует.


 
alles ©   (2006-08-03 14:46) [2]

Спасибо, и еще один вопрос:

procedure TConnectThread.Execute;
begin
     while not Terminated do
           Synchronize(OnWork);
end;

procedure TConnectThread.OnWork;
begin
  GlobalsVar.UserId := GetPayServiceSoap.UserLogin(FrmConnect.EdUser.Text,FrmConnect.EdPassword.Text);
  Terminate; <---МОЖНО ТУТ ПОСТАВИТЬ Terminate?
end;


 
Сергей М. ©   (2006-08-03 14:48) [3]

Можно.


 
Kolan ©   (2006-08-03 14:49) [4]

Terminate просто устанавливает флаг Terminated в True. Так что ставь где хочешь...


 
Сергей М. ©   (2006-08-03 14:50) [5]

Все что творится в методе Terminate - взводится флаг Terminated, который у тебя собссно и проверяется в условии while-цикла как условие выхода из него.


 
Германн ©   (2006-08-03 14:56) [6]


> procedure TConnectThread.Execute;
> begin
>      while not Terminated do
>            Synchronize(OnWork);
> end;

Где-то я уже это видел. :-)


 
Сергей М. ©   (2006-08-03 15:01) [7]


> Германн ©   (03.08.06 14:56) [6]


Сие есть шедевр приснопамятного Николая Кариха, неотесаные статьи которого многие годы совращают начинающих с пути истинного)


 
alles ©   (2006-08-03 15:01) [8]

Сергей М, в этом случяе никак не могу понять что надо писАть в TThread.WaitFor, не подскажите?


 
alles ©   (2006-08-03 15:07) [9]

2 Германн ©   (03.08.06 14:56) [6]
я на этой страницу прочитал
http://www.delphimaster.ru/articles/panov/index.html#PageTop
а что не так в этом коде?


 
Сергей М. ©   (2006-08-03 15:07) [10]

Ничего там писать не надо.

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

ThreadConnect := TConnectThread.Create;
ThreadConnect.WaitFor;


 
Kolan ©   (2006-08-03 15:08) [11]

Кстати
> OnWork

измени на DoWork.. это же не событие


 
alles ©   (2006-08-03 15:13) [12]

2 Сергей М. ©   (03.08.06 15:07) [10]
пробовал, не получяется. И TImage из FrmWait не прорисовается и TConnectThread не входит в TConnectThread :(


 
Германн ©   (2006-08-03 15:14) [13]


> alles ©   (03.08.06 15:07) [9]
>
> 2 Германн ©   (03.08.06 14:56) [6]
> я на этой страницу прочитал
> http://www.delphimaster.ru/articles/panov/index.html#PageTop
> а что не так в этом коде?
>

Не. Это явно не оттуда. Саша Панов не настолько глупый.
Не так в этом коде всё! Если в методе Execute нет ничего, кроме вызова Synchronize, то пропадает полностью смысл дополнительного потока.


 
Kolan ©   (2006-08-03 15:17) [14]

По сабжу. Поток может просто отправить сообщение...


 
alles ©   (2006-08-03 15:21) [15]

>alles ©   (03.08.06 15:13) [12]
прочитать как
пробовал, не получяется. И TImage из FrmWait не прорисовается и TConnectThread не входит в TConnectThread :(


 
alles ©   (2006-08-03 15:21) [16]

Terminate


 
Kolan ©   (2006-08-03 15:27) [17]

WaitFor doesn"t return until the thread terminates
Как я понял если ты этим воспользуешься то будешь ждать покак поток не завершится.. Тегда вопрос нах. вооюще доп. поток если ты его всеравно ждешь?

А вот событие:
OnTerminate (public)  Occurs after the thread"s Execute method has returned and before the thread is destroyed.  

Сбудется как раз по завершении...


 
alles ©   (2006-08-03 15:37) [18]

> Не. Это явно не оттуда. Саша Панов не настолько глупый.
согласен я ошибся, не заметил 2-й THread
Хорошо, тогда не подскажите как правильно делать так чтобы программа ожидала окончяние функций
GlobalsVar.UserId := GetPayServiceSoap.UserLogin(FrmConnect.EdUser.Text,FrmConnect.EdPassword.Text);
и в это же время рисовала FrmWait?


 
Сергей М. ©   (2006-08-03 15:44) [19]

WaitFor() в Д7 этому не препятствует, судя по исходникам ...

Лишь бы было понимание логики FreeOnTerminate-свойства, о коем ты не обмолвился ни словом ..


 
alles ©   (2006-08-03 15:46) [20]

Сергей М. ©   (03.08.06 15:44) [19]

constructor TConnectThread.Create;
begin
 inherited Create(True);    
 FreeOnTerminate := True;
 Self.Priority := tpHighest;
 Resume;                      
end;


 
Kolan ©   (2006-08-03 15:46) [21]

Ну я же объяснил..

Запускаешь поток.
Он там себе работу свою делает, а ты в это время в главном рисуешь.
Как поток закончится возникнит событие... Kolan ©   (03.08.06 15:27) [17] в нем и проверяещь то, что тебе надо... Для результата ожидания можно завести поле в потоке.

А лучьше не рисовать, а сделать gif картинку (имхо)...


 
Kolan ©   (2006-08-03 15:47) [22]

Ну я же объяснил..

Запускаешь поток.
Он там себе работу свою делает, а ты в это время в главном рисуешь.
Как поток закончится возникнит событие... Kolan ©   (03.08.06 15:27) [17] в нем и проверяещь то, что тебе надо...
Для результата ожидания можно завести поле в потоке.

А лучьше не рисовать, а сделать gif картинку (имхо)...


 
Сергей М. ©   (2006-08-03 15:55) [23]


> alles ©   (03.08.06 15:46) [20]


Хреново дело.
Можешь поиметь граблями по "мыслительному агрегату")

Убирай FreeOnTerminate = True, но при этом становись ответственным за уничтожение объекта..

ThreadConnect := TConnectThread.Create;
ThreadConnect.WaitFor; //пока ждем - события ввода-вывода GUI отрабатываются вовремя и в полной мере
РезультатРаботыПотока := ThreadConnect.ПолучитьРезультатРаботыПотока; //некий функц.метод, возвращающий результаты вычислений, проделанных доп.потоком
ThreadConnect.Free; //явно уничтожить объект - доп.поток - нам он больше не нужен


 
Сергей М. ©   (2006-08-03 15:56) [24]

А Кариха я когда-нть прибью при встрече)


 
Германн ©   (2006-08-03 16:23) [25]


> Сергей М. ©   (03.08.06 15:56) [24]
>
> А Кариха я когда-нть прибью при встрече)
>

Спокойнее Сергей, спокойнее. Наш тезка из Самары тоже очень нервничал по этому поводу. И где он теперь?
:-)


 
DiamondShark ©   (2006-08-03 23:17) [26]

*бьёццо в бессильной злобе апстол*
Ну зачем же так бездумно пользоваться копипастом?!!


> а что не так в этом коде?

То, что это не код! Это иллюстрация, схема. Рассчитана не на копирование, а на изучение человеком (который, если верить биологам, дважды сапиенс). Желательно, вместе со всем сопутствующим текстом.
Тогда можно заметить, что в предыдущем абзаце написано: "Как правило, если поток предназначен для выполнения многократно повторяющегося кода (цикла), то в Execute используется конструкция следующего вида".
Понимаете? "Как правило...", что не есть "всегда", и "многократно повторяющегося".
Где у тебя многократно повторяющиеся шаги? Ты зачем цикл скопировал?
Ты комментарии прочитал? Троеточие видел? В человеческих текстах оно обычно означает "и ещё много-много всякой всячины".
Ты зачем просто выбросил то, что не смог понять?


> WaitFor() в Д7 этому не препятствует, судя по исходникам

Что, серьёзно? Ой-вэй... Мне всегда не нравилось заворачивание простых по сути вещей в тяжеленные обёртки. Насуют всякого, чего не просят...
В пятёрке WaitFor ничем подобным не занимается.


 
DiamondShark ©   (2006-08-03 23:27) [27]

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   FThread: TThread;
   procedure Form3Show(Sender: TObject);
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

uses Unit3, Unit2;

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
 Form: TForm3;
begin
 Form := TForm3.Create(nil);
 Form.OnShow := Form3Show;
 FThread := TConnectThread.Create(true);
 FThread.FreeOnTerminate := true;
 FThread.OnTerminate := Form.ThreadTerminate;
 Form.ShowModal;
end;

procedure TForm1.Form3Show(Sender: TObject);
begin
 FThread.Resume;
end;

end.

==========================

unit Unit2;

interface

uses
 Classes;

type
 TConnectThread = class(TThread)
 private
   { Private declarations }
 protected
   procedure Execute; override;
 end;

implementation

uses
 Windows;

procedure TConnectThread.Execute;
begin
 Sleep(10000); // Типа, большая одноразовая работа
end;

end.

==========================

unit Unit3;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 ExtCtrls, StdCtrls, jpeg;

type
 TForm3 = class(TForm)
   Timer1: TTimer;
   Image1: TImage;
   Image2: TImage;
   procedure Timer1Timer(Sender: TObject);
   procedure FormClose(Sender: TObject; var Action: TCloseAction);
   procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
 private
   FCanClose: Boolean;
 public
   procedure ThreadTerminate(Sender: TObject);
 end;

var
 Form3: TForm3;

implementation

uses Unit2;

{$R *.DFM}

procedure TForm3.Timer1Timer(Sender: TObject);
begin
 Image1.Visible := not Image1.Visible;
 Image2.Visible := not Image2.Visible;
end;

procedure TForm3.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 Action := caFree;
end;

procedure TForm3.ThreadTerminate(Sender: TObject);
begin
 FCanClose := true;
 Close;
end;

procedure TForm3.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
 CanClose := FCanClose;
end;

end.


 
Kolan ©   (2006-08-04 00:46) [28]


> FThread.FreeOnTerminate := true;

Вот это все же лучьше прям в поток, а то забыть можно .. вдруг еще пригодится..

А так ,Имхо, это и есть верное решение.


 
Palladin ©   (2006-08-04 01:01) [29]

фф топку... фместе с аффтаром экзампэла, на основе которого реализовалось показанное...

ибо дырка через кою льется основной поток исполнения, ни фика не есть дуршлаг... а смысл дуршлага с дфуммя-тремя дырками просто теряется... еслив конечно они не ждут/отправляют данные из/в блокирующий сокет или не пишут/читаю com порт.... или нечто подобное... в существовании которого я сильно сомневаюсь...

и до сих пор не понятно, после 28 постов, чего там автор в потоке вообще собирается делать (по мимо синхронизации с основным потоком приложения, конечно)...


 
Kolan ©   (2006-08-04 01:24) [30]


> фф топку... фместе с аффтаром экзампэла

Это при

procedure TConnectThread.Execute;
begin
Sleep(10000); // Типа, большая одноразовая работа
end;

?


 
Германн ©   (2006-08-04 01:27) [31]


> и до сих пор не понятно, после 28 постов, чего там автор
> в потоке вообще собирается делать (по мимо синхронизации
> с основным потоком приложения, конечно)...
>

Имхо, автору нужна была Splash-форма, которая бы показывала, что программа не зависла, что "процесс" идёт и что надо просто подождать некоторое время пока сей процесс завершится. Он, опять же имхо, пошёл не туда и "вляпался" в потоки.


 
Kolan ©   (2006-08-04 01:30) [32]


> Он, опять же имхо, пошёл не туда и "вляпался" в потоки.


Вот я не пойму если надо:

> оказывала, что программа не зависла, что "процесс" идёт

и еще делать сам этот "процесс" - два дела... Это как без потоков одновременно сделать можно?


 
Германн ©   (2006-08-04 01:54) [33]


> Вот я не пойму если надо:
>
> > оказывала, что программа не зависла, что "процесс" идёт
>
> и еще делать сам этот "процесс" - два дела... Это как без
> потоков одновременно сделать можно

Да пойми ты одну простую вещь. "Показ" выполняется всегда в основном потоке!
А уж как реализовать выполнение "процесса" - это другое дело. В основном потоке или в дополнительном. В первом варианте показ обеспечивается вызовом Application.ProcessMessages или Repaint, во втором - вызовом метода Synchronize.
Ещё надо сказать о "возможности" пользователя производить действия в программе, пока "процесс" ещё идёт. Нужно ли это? И если да, то в какой мере?


 
Kolan ©   (2006-08-04 11:15) [34]


> Да пойми ты одну простую вещь. "Показ" выполняется всегда
> в основном потоке!

Я понимаю. Кстати не всегда, просто VCL компоненты не потоко безопасны...


> Application.ProcessMessages

Понятно, можно и так, но поток - более верное решение, имхо.


 
alles ©   (2006-08-04 12:19) [35]

>Он, опять же имхо, пошёл не туда и "вляпался" в потоки.
интересно, а никто из Вас даже не пытался никогда сделать активные(с роликом) Splash формы во время выполнения какой нибуть длительной операций. Может в инете где-то про это написанно. Можно канечьно оставить эту затею и использовать обычную форму, но для себя интереса просто интересно как это сделать


 
Пусик ©   (2006-08-04 12:24) [36]


>  но для себя интереса просто интересно как это сделать


Очень просто.
В основном потоке создается и показывается splash-форма, дополнительный поток проводит длительные вычисления.


 
Пусик ©   (2006-08-04 12:27) [37]


> Palladin ©   (04.08.06 01:01) [29]
> фф топку... фместе с аффтаром экзампэла, на основе которого
> реализовалось показанное...ибо дырка через кою льется основной
> поток исполнения, ни фика не есть дуршлаг... а смысл дуршлага
> с дфуммя-тремя дырками просто теряется...


Сложное высказывание, особенно с падонкавской лексикой.
Сложное, и малопонятное.


 
alles ©   (2006-08-04 12:47) [38]

2 Пусик ©   (04.08.06 12:24) [36]
я пробовал в основном потоке но при выполнение этой строки Splash форма не прорисовается, да и вообще программа как-бы виснет
 GlobalsVar.UserId := GetPayServiceSoap.UserLogin(FrmConnect.EdUser.Text,FrmConnect.EdPassword.Text);


 
DiamondShark ©   (2006-08-04 13:20) [39]

Земляк, не пропускай при чтении слова.


 
Пусик ©   (2006-08-04 13:42) [40]


> alles ©   (04.08.06 12:47) [38]


Значит, код неверный.



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

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

Наверх





Память: 0.56 MB
Время: 0.05 c
4-1146820955
Dimich1978
2006-05-05 13:22
2006.08.27
получить handle окна по неполному имени


1-1152854018
AlexeyT
2006-07-14 09:13
2006.08.27
Библиотека RegEx с поиском в файлах?


15-1154423861
VitV
2006-08-01 13:17
2006.08.27
Как обеспечить полную безопастность ICQ-общения?


2-1154978685
Spectrum2
2006-08-07 23:24
2006.08.27
UTF8toAnsi


2-1154665343
MSVN
2006-08-04 08:22
2006.08.27
TrackBar и время





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский