-
Добрый день. Есть следующий демокод:
unit uNewThread;
interface
uses
System.Classes,SysUtils,Dialogs,SyncObjs,StrUtils,ExtCtrls,Windows,
WideStrUtils,Vcl.Forms;
procedure ThreadDoJob(const aHost:string; var aErrorMsg:string; var aIsJobDone:Boolean);
type
DoJob = class(TThread)
private
fHost,fErrorMsg:string;
fIsJobDone:Boolean;
protected
procedure Execute; override;
public
property ErrorMsg:string read fErrorMsg;
property IsJobDone:Boolean read fIsJobDone;
constructor Create(const aHost:string; var aErrorMsg:string; var aIsJobDone:Boolean);
destructor Destroy; override;
end;
implementation
procedure ThreadDoJob(const aHost:string; var aErrorMsg:string; var aIsJobDone:Boolean);
var
ThreadJob:DoJob;
begin
ThreadJob:=DoJob.Create(aHost,aErrorMsg,aIsJobDone);
aErrorMsg:=ThreadJob.ErrorMsg;
aIsJobDone:=ThreadJob.IsJobDone;
end;
constructor DoJob.Create(const aHost:string; var aErrorMsg:string; var aIsJobDone:Boolean);
begin
inherited Create(False);
FreeOnTerminate := True;
Self.Priority := tpLower;
fHost:=aHost;
end;
destructor DoJob.Destroy;
begin
inherited Destroy;
end;
procedure DoJob.Execute;
var
flg:Boolean;
begin
flg:=true;
if flg then
begin
fIsJobDone:=TRUE;
fErrorMsg:='7777';
end
else
begin
fIsJobDone:=FALSE;
fErrorMsg:='6666';
end;
end. прогнозируемо aErrorMsg:=ThreadJob.ErrorMsg; и aIsMailSended:=ThreadJob.IsMailSended; выводят "ничего" в выше стоящий код Вопрос : как вывести результат работы потока в обработчики но без "Synchronize", трубы и прочего из той же оперы а через "property". если такое для потока вообще возможно. что то читал про OnTerminate но ничего канкретно применительно к "property" не нашлось.
-
при таком дизайне поток не нужен. свойство если читать то оно возвращает значение. без разницы что это за класс.
-
не "выводят" потому что там ничего нет. а ничего нет потому что не присвоено. дальше. если ты планируешь создать поток и в след строчке читать значение то зачем тебе вообще поток. переси код в экзекута в другую процедуру и не в потоке. будет все тоже самое.
-
ах да. там еще и фрионтерминате. просто интересно. как ты собрался ловить ту наносекунду когда результат уже готов но поток еще не успел самовыпилиться?
-
этот и есть мой вопрос - как
-
> Вопрос : как вывести результат работы потока в обработчики > но без "Synchronize", трубы и прочего из той же оперы а через "property".
Надо дождаться окончания работы потока (т.е. окончания выполнения DoJob.Execute) и после этого прочитать property
-
тока после экзекута никакого свойства уже нет как и самого потока. к тому же дождаться это эквивалентно тому когда екзекут выполняется в основном потоке
-
> icp © (05.06.18 06:45) [6] > тока после экзекута никакого свойства уже нет как и самого потока.
Чего это вдруг? Потока (операционной системы) конечно нет, а Delphi-объект - куда ж он делся? на месте он. Можно читать/писать свойства без проблем.
> к тому же дождаться это эквивалентно тому когда екзекут выполняется в основном потоке
"Ждать" не эквивалентно "стоять и ждать". Можно заниматься чем-то полезным, проверяя периодически не завершился ли поток. Ну или не проверять, а как-то иначе просигнализировать основному потоку "я выполнился" (сообщение через PostMEssage в главную форму кинуть хотя бы, например, как самое простое)
-
с таво вдруг что фрионтерминэйт. екзекут завершился и кирдык всему экземпляру настает
-
сказано же по русски. что в таком дизайне поток здесь нафик не нужен.
-
> Pcrepair © (04.06.18 19:33)
Кстати, вставьте вот такую простую штуку - и, думаю, свойства у вас сразу прочитаются.
procedure ThreadDoJob(const aHost:string; var aErrorMsg: string; var aIsJobDone:Boolean); var ThreadJob:DoJob; begin ThreadJob:=DoJob.Create(aHost,aErrorMsg,aIsJobDone); Sleep(0); aErrorMsg:=ThreadJob.ErrorMsg; aIsJobDone:=ThreadJob.IsJobDone; end;
-
> icp © (05.06.18 08:14) [8] > с таво вдруг что фрионтерминэйт.
Да, не заметил, извиняюсь. Его убрать, конечно, смысла с него нет, тем более в данном случае.
-
> icp © (05.06.18 08:15) [9] > сказано же по русски. > что в таком дизайне поток здесь нафик не нужен.
Ясно же, что пример крайне демонтрационый как раз для понимания всех этих моментов
-
вот для понимания я и сказал ему. что если делать как он хочет то не надо лепить поток. ибо смысла ноль
-
> icp © (05.06.18 08:14) [8]
> екзекут завершился и кирдык всему экземпляру настает
Сначала выполнится онтерминэйт в первичном потоке, а уж потом "екзекут завершился и кирдык всему".
-- Regards, LVT.
-
да да. остается только поймать этот миг. когда уже готово но все еще живо. без извратов то неможно
-
> icp © (05.06.18 08:51) [15]
> остается только поймать этот миг. > когда уже готово но все еще живо.
Я ж и говорю, что в OnTerminate этих мгновений м.б. хоть 17.
-- Regards, LVT.
-
> icp © (05.06.18 08:22) [13]
> что если делать как он хочет то не надо лепить поток
Видимо, он хочет Fire & Forget. Ненаказуемо.
-- Regards, LVT.
-
какой же тут форгет если он паблик проперти придумал. здесь ремембер ол лайф тайм
-
подкину дровишек. вот так демо работает. несмотря на выше опубликованный базар unit uNewThread;
interface
uses
System.Classes,SysUtils,Dialogs,SyncObjs,StrUtils,ExtCtrls,Windows,
WideStrUtils,Vcl.Forms;
procedure ThreadDoJob(const aHost:string; var aErrorMsg:string; var aIsJobDone:Boolean);
type
DoJob = class(TThread)
private
fHost,fErrorMsg:string;
fIsJobDone:Boolean;
protected
procedure Execute; override;
public
property ErrorMsg:string read fErrorMsg;
property IsJobDone:Boolean read fIsJobDone;
constructor Create(const aHost:string; var aErrorMsg:string; var aIsJobDone:Boolean);
destructor Destroy; override;
end;
implementation
procedure ThreadDoJob(const aHost:string; var aErrorMsg:string; var aIsJobDone:Boolean);
var
ThreadJob:DoJob;
begin
ThreadJob:=DoJob.Create(aHost,aErrorMsg,aIsJobDone);
ThreadJob.WaitFor;
aErrorMsg:=ThreadJob.ErrorMsg;
aIsJobDone:=ThreadJob.IsJobDone;
ThreadJob.Destroy;
end;
constructor DoJob.Create(const aHost:string; var aErrorMsg:string; var aIsJobDone:Boolean);
begin
inherited Create(False);
FreeOnTerminate := FALSE;
Self.Priority := tpLower;
fHost:=aHost;
end;
destructor DoJob.Destroy;
begin
inherited Destroy;
end;
procedure DoJob.Execute;
var
flg:Boolean;
begin
flg:=false;
if flg then
begin
fIsJobDone:=TRUE;
fErrorMsg:='7777';
end
else
begin
fIsJobDone:=FALSE;
fErrorMsg:='6666';
end;
ReturnValue:=1;
end;
end.
все работает. данные входят и выходят
|