Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / потоки(TThread) и свойства(property), не все понятно / 25 сообщений из 29, страница 1 из 2
04.06.2018, 16:12
    #39655031
Pcrepair
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
Добрый день. Есть следующий демокод:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
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,aIsMailJobDone);
  aErrorMsg:=ThreadJob.ErrorMsg; 
  aIsMailSended:=ThreadJob.IsMailSended;
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;  (*or FALSE just for fun*)

  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" не нашлось.
...
Рейтинг: 0 / 0
04.06.2018, 16:18
    #39655042
DesWind
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
Pcrepair,
ИМХО, проще всего отправить сообщение об окончании работы потока.
...
Рейтинг: 0 / 0
04.06.2018, 16:22
    #39655046
Pcrepair
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
лутше всего вначале прочитать топик а потом писАть ответ
...
Рейтинг: 0 / 0
04.06.2018, 16:55
    #39655088
Zelius
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
Pcrepair,

защищать доступ критическими секциями. но тут другая проблема, поток самоуничтожаем, поэтому в момент считывания его может и не быть уже
...
Рейтинг: 0 / 0
04.06.2018, 17:16
    #39655104
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
PcrepairВопрос : как правильно вывести результат работы потока в обработчики но без "Synchronize" и прочего из той же оперы а через "property". если такое для потока вообще возможно. что то читал про OnTerminate но ничего канкретно применительно к "property" не нашлось.

А что вы хотите "вывести" из потока, если у вас в конструкторе "FreeOnTerminate := True;"? Как только завершается выполнение Thred.Execute(), то у вас поток уже не существует. Это во-первых.

Во-вторых:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure  ThreadDoJob(const aHost:string; var aErrorMsg:string; var aIsJobDone:Boolean);
var
  ThreadJob:DoJob;
begin
  ThreadJob:=DoJob.Create(aHost,aErrorMsg,aIsMailJobDone);
  aErrorMsg:=ThreadJob.ErrorMsg; // сюда вы [возможно] попадёте, когда поток ещё не выполнился, так откуда там возьмётся значение?..
  aIsMailSended:=ThreadJob.IsMailSended;
end;


ИМХО почитайте справку про TThread.WaitFor и вообще статьи на тему взаимодействия потоками, т.к. непонятно зачем в вашем случае он вообще нужен.
...
Рейтинг: 0 / 0
04.06.2018, 17:41
    #39655121
DesWind
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
Pcrepair,
Я по коду ориентировался, если в конце Execute сделать SendMessage, то поток не уничтожится пока не буде обработано сообщение об окончании работы потока.
...
Рейтинг: 0 / 0
04.06.2018, 18:57
    #39655146
makhaon
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
Сложно сказать, что именно нужно. Но пока что послать синхронное сообщение об окончании - лучшая идея. Иначе можем напороться на отсутствующий экземпляр, со всеми последствиями. Либо где-то снаружи результат запоминать, что явно хуже.
...
Рейтинг: 0 / 0
04.06.2018, 19:16
    #39655152
Pcrepair
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
неужто никто топик до конца не читает?

авторВопрос : как правильно вывести результат работы потока в обработчики но без "Synchronize" и прочего из той же оперы а через "property". если такое для потока вообще возможно. что то читал про OnTerminate но ничего канкретно применительно к "property" не нашлось.
...
Рейтинг: 0 / 0
04.06.2018, 19:28
    #39655155
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
PcrepairВопрос : как правильно вывести результат работы потока в обработчики но без "Synchronize" и прочего из той же оперы а через "property".
Вопрос звучит примерно так: "Как мне доехать на автомобиле из Москвы в Ленинград, но без бензина и прочего из той же серии, а через руль?"

К сожалению, Ваш текст показывает столь малое знакомство с предметом, что какой-либо осмысленный диалог практически невозможен. Если Вам быстро нужный результат, погуглите что-нибудь типа "как вернуть результат из потока в Delphi" и добросовестно скопируйте тот или иной пример, а если хотите разобраться и понимать происходящее - прочитайте базовые материалы по теме, тогда сможете задавать более осмысленные вопросы.
...
Рейтинг: 0 / 0
04.06.2018, 19:31
    #39655156
Pcrepair
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
а по существу?
...
Рейтинг: 0 / 0
04.06.2018, 19:57
    #39655169
makhaon
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
Pcrepair,
авторнеужто никто топик до конца не читает?
Вот вот :)
авторЛибо где-то снаружи результат запоминать, что явно хуже.
...
Рейтинг: 0 / 0
04.06.2018, 20:12
    #39655184
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
Pcrepairнеужто никто топик до конца не читает?

авторВопрос : как правильно вывести результат работы потока в обработчики но без "Synchronize" и прочего из той же оперы а через "property". если такое для потока вообще возможно. что то читал про OnTerminate но ничего канкретно применительно к "property" не нашлось.
OnTerminate вызывается в контексте главного потока, там ничего защищать не надо
...
Рейтинг: 0 / 0
04.06.2018, 20:12
    #39655185
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
Pcrepairа по существу?
А по существу тут программист нужон (С)
...
Рейтинг: 0 / 0
04.06.2018, 21:05
    #39655215
Pcrepair
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
ну что же... а теперь для всех шибка грамотных и не очень, а также кому интересно ПРАВИЛЬНЫЙ ОТВЕТ!

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
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;  (*or FALSE just for fun*)

  if flg then
  begin
    fIsJobDone:=TRUE;
    fErrorMsg:='7777';
  end
  else
  begin
    fIsJobDone:=FALSE;
    fErrorMsg:='6666';
  end;

  ReturnValue:=1;
end;

end.



данные входят и выходят. через параметры
...
Рейтинг: 0 / 0
04.06.2018, 21:14
    #39655217
чччД__
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
Pcrepair,

архигениально.
...
Рейтинг: 0 / 0
04.06.2018, 22:17
    #39655237
krapotkin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
freeOnTerminate вовсе не убивает поток сразу после Execute
поэтому абсолютно спокойно поток сходит в обработчик OnTerminate, как уже написано, в главном потоке
там у него можно забрать результаты трудов
а после этого он тихо умрет

а то что вы написали, скорее всего надаёт AV, т.к. синхронизации никакой нет
и то что ссылки на переменные вы пихаете через конструктор, ну ничего не меняет
...
Рейтинг: 0 / 0
04.06.2018, 22:40
    #39655244
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
Pcrepairну что же... а теперь для всех шибка грамотных и не очень, а также кому интересно ПРАВИЛЬНЫЙ ОТВЕТ!
А теперь внимание, вопрос: нахрена там TThread, если код из Execute() можно напрямую запихнуть в ThreadDoJob() с тем же результатом?
...
Рейтинг: 0 / 0
04.06.2018, 22:42
    #39655245
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
А самое прикольное, это вот эта конструкция:
Код: pascal
1.
2.
3.
4.
5.
6.
begin
  inherited Create(False);
  FreeOnTerminate := FALSE;
  Self.Priority := tpLower;
  fHost:=aHost;
end;


Поток начнёт выполнение раньше, чем получит адрес хоста.
А, учитывая что fHost - это строка, то адок будет тот ещё.
...
Рейтинг: 0 / 0
04.06.2018, 22:42
    #39655246
Pcrepair
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
задача и была именно такой - напихать ссылки через конструктор. сказано ведь -ДЕМОКОД
...
Рейтинг: 0 / 0
04.06.2018, 22:45
    #39655248
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
Pcrepairзадача и была именно такой - напихать ссылки через конструктор. сказано ведь -ДЕМОКОД
У этого демокода только одно применение - показать как не надо делать.
...
Рейтинг: 0 / 0
04.06.2018, 22:47
    #39655249
Pcrepair
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
а может и так
...
Рейтинг: 0 / 0
05.06.2018, 00:04
    #39655271
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
Pcrepair[src delphi]
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;осталось расставить try-finally
alekcvpА теперь внимание, вопрос: нахрена там TThread, если код из Execute() можно напрямую запихнуть в ThreadDoJob() с тем же результатом? самое интересное я одно применение такому коду знаю (полезное имею ввиду, даже видел в проде), но врят ли ТС так глубоко копал.

правды для :
alekcvpПоток начнёт выполнение раньше, чем получит адрес хоста.не начнёт

krapotkinа то что вы написали, скорее всего надаёт AV, т.к. синхронизации никакой нет
и то что ссылки на переменные вы пихаете через конструктор, ну ничего не меняетне найдёт (если речь про 21467861 ), очень сильно меняет
...
Рейтинг: 0 / 0
05.06.2018, 00:21
    #39655278
makhaon
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
Pcrepair,

:facepalm: как обычно :)
...
Рейтинг: 0 / 0
05.06.2018, 00:25
    #39655279
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
Pcrepairкак правильно вывести результат работы потока в обработчики но без "Synchronize" и прочего из той же оперы
Как бы вам сказать...
Работать с потоками без объектов синхронизации, это примерно как крутить барабан из 12 патронов с 11-ю заряженными у виска.
Если вы реально не хотите ничего синхронизировать, тогда вам в помощь lockfree, но в вашем случае, это как слетать в магазин на шаттле.

Вообще если вам надо выполнить работу и получить результат то можете сделать так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
type
  TRez = record
    Msg: string;
    Success: Boolean;
  end;
var
  a: IFuture<TRez>;
  Rez: TRez;
begin
  a := TTask.Future<TRez>(
    function: TRez
    var
      flg:Boolean;
    begin
      flg:=true;  (*or FALSE just for fun*)

      if flg then
      begin
        Result.Success := True;
        Result.Msg := '7777';
      end
      else
      begin
        Result.Success := False;
        Result.Msg := '6666';
      end;
    end
  );
  a.Start();
  // blabla
  Rez := a.Value;
  //
end;
...
Рейтинг: 0 / 0
05.06.2018, 00:52
    #39655284
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
потоки(TThread) и свойства(property), не все понятно
kealon(Ruslan)alekcvpПоток начнёт выполнение раньше, чем получит адрес хоста.не начнёт
Да, действительно, защиту от дурака встроили, умнО :)
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / потоки(TThread) и свойства(property), не все понятно / 25 сообщений из 29, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]