-
Добрый день. Есть следующий демокод:
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.
все работает. данные входят и выходят
-
> icp © (05.06.18 09:32) [18]
> какой же тут форгет если он паблик проперти придумал.
Какая разница паблик не паблик, если все в одном флаконе.
Я думаю, что у ТС уже есть все необходимое для
выполнения домашнего задания.
--
Regards, LVT.
-
> Pcrepair © (05.06.18 09:39) [19]
> подкину дровишек. вот так демо работает. несмотря на выше
> опубликованный базар
Зря за базаром не следишь, бо фигню написал.
О чем еще в [1] сказано.
--
Regards, LVT.
-
разница такая.
если свойство то нужна ссылка на экземпляр.
посему надо помнить про поток весь его жизненный цикл.
никакого форгета здесь и близко не будет
-
вейтфор. как это прелестно....
впрочем очередной
стотысячный велосипедист за последние 18 лет
на дм.
они словно однояйцевые как под копирку.
когда в потоеи начинают.
-
процессор выполнял полезную работу в основном потоке.
затем ему сказали потратить кучу тактов и переключиться на вторичный и продолжить творить что то полезное. основной при этом тупо стоит и ничего не делает.
итого.
сделали ту же работу но за большее время и потратив
впустую ресурсы на вторичный поток.
конгратьюлейшен мистер
-
> icp © (05.06.18 10:20) [22]
> если свойство то нужна ссылка на экземпляр.
> посему надо помнить про поток весь его жизненный цикл.
type
TMyThread = class(TThread)
public
prop: Longint;
procedure Execute; override;
end;
procedure TMyThread.Execute;
begin
prop := GetTickCount;
Sleep(3000);
end;
procedure Tform1.PostMort;
begin
with Sender as TMyThread do
ShowMessage(IntToStr(prop));
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
with TMyThread.Create(False) do
begin
FreeOnTerminate := True;
OnTerminate := PostMort;
end;
ShowMessage('FAF');
end;
--
Regards, LVT.
-
и чо?
до самого терминэйт работаем со ссылкой на поток.
а типа если она сендером прилетела то как бы никто не заметил.
это не настоящий выстрелил и забыл.
-
> icp © (05.06.18 17:43) [26]
> и чо?
Усложним задачу.
Закоментируем
// ShowMessage('FAF');
и жмем кнопаку 40+ раз
> до самого терминэйт работаем со ссылкой на поток.
(следим за руками) ссылки не храним, за потоком не следим
> а типа если она сендером прилетела то как бы никто не заметил
дык, она ж сама прилетела, я про нее и забыл.
Так что, все по взрослому, никакого Жюля.
--
Regards, LVT.
-
все так просто?
навесили он терминейт.
оке.
и теперь мы не просто помним о потоке (а мы помним я гарантирую это)
так мы еще и взяли на себя обязательство что экземпляр класса с обработчиком будет жить дольше самого потока.
а так да как бы не помним
-
> icp © (06.06.18 09:43) [28]
> так мы еще и взяли на себя обязательство что экземпляр класса
> с обработчиком будет жить дольше самого потока.
Ой, как страшно жить.
Выбор объекта необходимого уровня - еще тот бином.
Не умеешь ставить блок - ставь бутылку.
Это даже не молчаливое завершение процесса,
бо все в первичном потоке.
--
Regards, LVT.
-
нутакчо.
как бы забываем
но на самом деле живем и помним.
и уйти раньше терминэйта нельзя ибо будет взрыв.
о чем спортм то?