powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как организовать ожидание пока Thread не отработает задание
78 сообщений из 78, показаны все 4 страниц
Как организовать ожидание пока Thread не отработает задание
    #39642966
Thread
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте!

Никак не могу додумать, как такое сделать. Прошу помощи!


Такая задача:

Есть thread #1 , в начале Execute которого создаю всякие вспомогательные COM-объекты, в конце их уничтожаю.
Thread #1 обычно должен простаивать, ничего не делая. Но время от времени какой-нибудь thread #2/#3/#4/... должен остановиться, бросить этому thread #1 данные и ждать, пока тот их не обработает. После чего вызвавший thread #2/#3/#4/... продолжит свою работу, а thread #1 будет ждать нового задания

заранее спасибо
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39642967
Thread
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39642978
_Трейдер_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть много способов: Interlocked функции, Event-ы, мьютексы, etc...
Но вот в чем вопрос на зачем тебе этот поток, если во время его работы остальные потоки уснут?
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643001
Thread
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Thread #1 нужен потому, что:

1) это не должен быть главный thread
2) из-за COM объектов
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643010
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С моей библиотекой - легко. :)
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643014
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Thread,

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

I/O Completion Ports

Thread,
обходишь косяки в RPC?
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643017
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А что потоки 2_3_4 делают, кроме отправки задания и ожидания окончания? Нужны ли они?
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643035
Thread
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Делают всякое, но, пожалуйста, давайте не будем отвлекать топик на это.

Вопрос (просьба) помочь с кодом, как сделать эту задержку.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643040
Thread
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kealon(Ruslan)Thread,

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

I/O Completion Ports

Thread,
обходишь косяки в RPC?


Спасибо, посмотрю.
Обхожу косяки ограниченности ресурсов
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643085
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Thread,

сделать поток с очередью сообщений и посылать туда сообщения из других потоков через SendMessage
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643124
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZeliusThread,

сделать поток с очередью сообщений и посылать туда сообщения из других потоков через SendMessageога ..., и получить в полной красе то с чем он борется
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643127
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)ZeliusThread,

сделать поток с очередью сообщений и посылать туда сообщения из других потоков через SendMessageога ..., и получить в полной красе то с чем он борется
еще раз перечитал - все соответствует поставленной задаче
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643141
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zeliusеще раз перечитал - все соответствует поставленной задаче
Да 100% очередь нужна. Например, виндовая c SendMessage.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643150
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zeliuskealon(Ruslan)пропущено...
ога ..., и получить в полной красе то с чем он борется
еще раз перечитал - все соответствует поставленной задачеугу, особенно замечательно когда у тебя посыпятся "Canvas don't allow drawing" и прочие прелести вроде дедлоков на ровном месте
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643153
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)особенно замечательно когда у тебя посыпятся "Canvas don't allow drawing" и прочие прелести вроде дедлоков на ровном местеС каких делов они посыпятся?
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643168
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockС каких делов они посыпятся?
MSDNThe sending thread is blocked until the receiving thread processes the message. However, the sending thread will process incoming nonqueued messages while waiting for its message to be processed. To prevent this, use SendMessageTimeout with SMTO_BLOCK set. For more information on nonqueued messages, see Nonqueued Messages.
Если будешь использовать не из главного потока проблем особых не будет, но всё меняется...

конкретно с "Canvas don't allow drawing" проблема в связке

Код: pascal
1.
2.
3.
4.
5.
6.
    FCanvas.Handle := DC;
    try
      ...
    finally
      FCanvas.Handle := 0;
    end;

которая везде раскидана по VCL
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643174
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Thread,
ZeroMQ + REQ-REP по протоколу inproc.
Кодировать три минуты, очередь искаропки, все бесплатно.
Отправляется сообщение, сообщение поступает в очередь треда - воркера, ждём ответа. Воркер, завершив предыдущее задание, выгребают из очерди следующее, работает, отправляет ответ заказчику. Заказчик, отправив задание, спит до получения ответа воркера. Никаких семафоров, мьютексов и прочей дичи, только сообщения.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643178
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan),

Ну, значит тогда можно использовать SendMessageTimeout with SMTO_BLOCK
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643188
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,

можно и так, но IOС Port всё равно проще и прозрачнее
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643194
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan),

ничё се проще :)
ну кому как.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643244
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockkealon(Ruslan),

ничё се проще :)
ну кому как.

чуть переделать
Код: 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.
type
  TIOPort = class(TObject)
  private
    FPort: THandle;
  public
    constructor Create();
    destructor Destroy(); override;
    procedure PushBack(const AValue: Integer); inline;
    function PopFront(out AValue: Integer): Boolean; inline;
  end;
{ TIOPort }

constructor TIOPort.Create;
begin
  inherited Create;
  FPort := CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);
  if (FPort = 0) then
    RaiseLastOSError();
end;

destructor TIOPort.Destroy;
begin
  if FPort <> 0 then begin
    CloseHandle(FPort);
    FPort := 0;
  end;
  inherited Destroy;
end;

function TIOPort.PopFront(out AValue: Integer): Boolean;
var
  TmpBytes: DWORD;
  TmpOverlapped: POverlapped;
begin
  Result := GetQueuedCompletionStatus(FPort, TmpBytes, ULONG_PTR(AValue), TmpOverlapped, INFINITE);
end;

procedure TIOPort.PushBack(const AValue: Integer);
begin
  if (not PostQueuedCompletionStatus(FPort, 0, UIntPtr(AValue), nil)) then
    RaiseLastOSError();
end;

строчек 50 добавится
и сравни с SendMessage : класс зарегать, протянуть оконную процу, ещё схлопать с организацией завершением цикла
ну его нафиг
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643272
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ThreadВопрос (просьба) помочь с кодом, как сделать эту задержку.
Ну, как-то то именно этому посвящена целая книга, если конечно делать все thread-like. А кроме книги есть еще куча материалов.

А по вопросу... Чем не устраивает:
Код: pascal
1.
2.
3.
  repeat
    Application.ProcessMessages();
  until Флаг;
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643282
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643283
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stanilarА по вопросу... Чем не устраивает:
Код: pascal
1.
2.
3.
  repeat
    Application.ProcessMessages();
  until Флаг;

А что случится, если в этот момент я закрою окно?
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643285
энди
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
begin

  // Этот код выполняется в главном потоке (например, Button1Click)

  EnterWorkerThread;
  try

    { Этот код выполняется во вторичном потоке }
    { Хотя это код Button1Click, но он выполняется, как если бы он был }
    { помещён в TThread.Execute. }

  finally
    LeaveWorkerThread;
  end;

  // Этот код выполняется в главном потоке

end;



http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=1355
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643288
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КвейдА что случится, если в этот момент я закрою окно?

Это зависит от наличия программиста на проекте.

Код: pascal
1.
2.
3.
4.
5.
6.
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  repeat
    Application.ProcessMesagess();
  until Флаг ;
end;
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643290
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan),

не надо ничего регистрировать, уже все готовое есть - AllocateHWnd и цикл стандартный выборки из очереди сообщений
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643293
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zeliuskealon(Ruslan),

не надо ничего регистрировать, уже все готовое есть - AllocateHWnd и цикл стандартный выборки из очереди сообщенийт.е. то что она не threadsafe вас никак не смущает?
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643307
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan),

есть такая фигня, да, но не смущает, я ею часто пользуюсь, небезопасность легко обходится вызовом в главном потоке перед созданием доп потока
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643309
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zeliusнебезопасность легко обходится вызовом в главном потоке перед созданием доп потока
Как же оно тогда, окошко бедное, будет работать через цикл сообщения доп. потока?
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643332
Идиотизм использовать несколько потоков,что бы в этих потоках ждать выполнения запущенного потока.

Тогда и одного потока с головой хватит, написав код линейно
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643334
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockZeliusнебезопасность легко обходится вызовом в главном потоке перед созданием доп потока
Как же оно тогда, окошко бедное, будет работать через цикл сообщения доп. потока?
нее, вызвать в главном, а потом в дополнительном спокойно вызывать
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643345
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zeliusнее, вызвать в главном, а потом в дополнительном спокойно вызыватьMakeObjectInstance тоже не threadsafe, шикарно будет когда на массовом проекте встретите ещё такого же оптимизатора
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643346
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МиксионисюниИдиотизм использовать несколько потоков,что бы в этих потоках ждать выполнения запущенного потока.

Тогда и одного потока с головой хватит, написав код линейноабсолютно согласен, осталось только микрософт убедить подправить пару мелочей
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643349
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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.
procedure Thread1.Execute;
var
  Res: Cardinal;
  Handles: array[0..0] of THandle;
begin
  .............
  Handles[0] := TermanateEvent;
  while not Terminated do begin
    Res := MsgWaitForMultipleObjects(1, @Handles[0], False, INFINITE, QS_ALLPOSTMESSAGE);
    case Res of
      WAIT_OBJECT_0: Terminate;
      WAIT_OBJECT_0 + 1: DoPeekMessages;
  end;
end;

procedure TThread1.DoPeekMessages;
var
  LMsg: TMsg;
begin
  while PeekMessage(LMsg, 0, 0, 0, PM_REMOVE) do
    DoMessage(LMsg);
end;

procedure TThread1.DoMessage(const AMsg: TMsg);
var
  LMsg: TMessage;
begin
  LMsg.Msg := AMsg.message;
  LMsg.WParam := AMsg.wParam;
  LMsg.LParam := AMsg.lParam;
  LMsg.Result := 0;
  Dispatch(LMsg);
end;

procedure TThread1.TMMyMsg(var AMsg: TMessage);
begin
  DoProcess(Pointer(AMsg.WParam));
  SetEvent(AMsg.LParam);
end;

procedure Thread2.Execute;
var
  WaitEvent: THandle;
begin
  WaitEvent := CreateEvent(nil, False, False, nil);
  ............
  PostThreadMessage(Thread1.ThreadID, TM_MY_MSG, WPARAM(@Data), WaitEvent);
  WaitForSingleObject(WaitEvent, INFINITE);
  ............
  CloseHandle(WaitEvent);
end;
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643369
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

с PostThreadMessage те же прелести что и с SendMessage 21402607 , и обходной функции нет
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643396
Thread
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо всем за обсуждение
Я здесь, никуда не делся.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643463
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МиксионисюниИдиотизм использовать несколько потоков,что бы в этих потоках ждать выполнения запущенного потока.

Тогда и одного потока с головой хватит, написав код линейноНе идиотизм, если нужна очередь - строго последовательное исполнение заданий, полученных из разных потоков.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643464
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZeliusYuRockпропущено...

Как же оно тогда, окошко бедное, будет работать через цикл сообщения доп. потока?
нее, вызвать в главном, а потом в дополнительном спокойно вызыватьЧто вызывать? Если ты сделал CreateWindow в главном потоке, то это окно будет "принажлежать" главному потоку, и сообщения ему будут в нем приходить только.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643465
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockМиксионисюниИдиотизм использовать несколько потоков,что бы в этих потоках ждать выполнения запущенного потока.

Тогда и одного потока с головой хватит, написав код линейноНе идиотизм, если нужна очередь - строго последовательное исполнение заданий, полученных из разных потоков.
Тебе о другом говорят: отправляешь задание и ждешь результатов - чем лучше ожидание результата по сравнению с (например) просто вызовом нужной функции прямо в контексте данного треда?
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643466
YuRock,



Пояснение, у нас есть уже поток, вместо того что бы вызывать новые потоки, мы можем вызывать функции



Я уже чувствую как твои идеалы рушатся на корню.


чччД слишком заумно высказал
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643472
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччДYuRockпропущено...
Не идиотизм, если нужна очередь - строго последовательное исполнение заданий, полученных из разных потоков.
Тебе о другом говорят: отправляешь задание и ждешь результатов - чем лучше ожидание результата по сравнению с (например) просто вызовом нужной функции прямо в контексте данного треда?Ничем только в случае, если это задание выполняется изолированно. А если это команда на устройство на открытом компорте? Нужна и очередь, и ожидание исполнения.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643474
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МиксионисюниЯ уже чувствую как твои идеалы рушатся на корню.


чччД слишком заумно высказалчччД правильно сказал, только ты не понял, что он сказал об общем (и частном в то же время) случае. Да, бывает, такое бессмысленно, и конечно можно просто вызвать функцию. А бывает - что жругого выхода нет и нвдо ждать окончания задания именно в другом потоке (который обрабатывает очередь).
Думаю, именно эта задача у ТС - активыксы какие-то создаются, видимо, для работы с устройствами.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643478
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockМиксионисюниИдиотизм использовать несколько потоков,что бы в этих потоках ждать выполнения запущенного потока.

Тогда и одного потока с головой хватит, написав код линейноНе идиотизм, если нужна очередь - строго последовательное исполнение заданий, полученных из разных потоков.для этого достаточно критической секции


YuRockZeliusпропущено...

нее, вызвать в главном, а потом в дополнительном спокойно вызыватьЧто вызывать? Если ты сделал CreateWindow в главном потоке, то это окно будет "принажлежать" главному потоку, и сообщения ему будут в нем приходить только.
я так понял, что он имел ввиду что там ленивая инициализация и достаточно один раз предварительно запустить, но это не так, дело портит MakeObjectInstance
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643479
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)для этого достаточно критической секцииНу правильно. Одной критической секции достаточно для организации элементарной очереди. Без всяких виндовых SendMessage, IOCP и проч.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643480
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МиксионисюниТогда и одного потока с головой хватит, написав код линейно

Линейный код сложно разделить на модули.

Именно тот случай, когда ощущается отсталость Дельфи. В данном случае в виде малого количества компонент для реактивного программирования.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643482
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stanilar,

Спасибо, поржал перед сном
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643488
на самом то деле, задача выглядит так

1) Создание всех ком объектов
2) Создание цикла - который будет ждать некий конечный статус, а пока его нет - выполнятся бесконечно
3) Делать проверку ту самую (Которую хотели вынести в отдельный поток, и поток первый ждал бы пока второй поток отработает, и вернёт эту метку на проверку)
4) В проверке делать что хотелось
5) После получения метки конца главного цикла, после цикла уничтожить созданные ком объекты - избавить код от постоянном пересоздание и удалении.



stanilar ,

Ржу не могу)
Модули = функции.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643489
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МиксионисюниМодули = функции

А меня учили что в Дельфи для модульности используются Unit'ы.

МиксионисюниРжу не могу)

Грех смеяться над отсталыми.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643558
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stanilarМиксионисюниТогда и одного потока с головой хватит, написав код линейно

Линейный код сложно разделить на модули.

Именно тот случай, когда ощущается отсталость Дельфи. В данном случае в виде малого количества компонент для реактивного программирования.

Закусывать надо.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643578
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonЗакусывать надоКстати, "реактивное программирование" - интересный термин. Новый наверно, раньше не встречал.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643579
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockmakhaonЗакусывать надоКстати, "реактивное программирование" - интересный термин. Новый наверно, раньше не встречал.
Это, наверное, как экстремальное программирование, когда мысль прет
и хочется в туалет.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643586
stanilarА меня учили что в Дельфи для модульности используются Unit'ы.


Простой пример
Код: pascal
1.
Result  := UnitName.FunctionName();



В идеале он сам должен подхватит ближайшую объявленную функцию
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643643
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanЭто, наверное, как экстремальное программирование, когда мысль прет

А почему не: "А зачем это в дельфистам"?


YuRockКстати, "реактивное программирование" - интересный термин. Новый наверно, раньше не встречал.
Чуть постарше Дельфи. Наверное.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643646
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МиксионисюниПростой пример

Пример чего? Что для разделения нужны юниты?
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643648
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stanilarYuRockКстати, "реактивное программирование" - интересный термин. Новый наверно, раньше не встречал.
Чуть постарше Дельфи. НаверноеПогуглил. Да, есть такое.
Нет, не старше, но это не важно.
Важно то, что в "реактивном программировании" речь идет о потоках данных.
А в этом топике - о потоках кода.
Это, как бы, разные сущности.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643654
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockА в этом топике - о потоках кода.

Автору нужно получить событие о завершении работы расчетного потока. Как раз событие завершение работы расчетного потока и есть поток данных. По сути реактивность это те-же потоки.

На практике можно было бы отказаться от того потока, в котором идет ожидание, заменив его на две процедуры: генерация события передачи данных в поток и событие получение результата расчета. Как раз удобно, когда слушателей много.

Удобно именно с точки зрения оформления кода. Конечно, можно посмотреть есть ли что в OTL, но дельфя у меня уже давно не стоит.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643658
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stanilar,

Всё, что ты написал, делается элементарно и на делфи и на чем угодно. Тупо вызвать коллбэки (извини, "события") у подписанных "читателей".

Только это ад несусветный. Да, иногда - удобно. Как в экселе - одна ячейка другие обновляет. Но в общем - нет.

Автору нужно не это, не огород "событий" городить. Ему нужно просто организовать очередь и в других потоках дожидаться выполнения заданий, добавленных в эту очередь.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643662
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockделается элементарно ...
В сферическом примере - да. На практике будут разные ситуации типа преждевременного завершения ожидающего потока. Или ожидания разными потоками получения одинаковых данных.

YuRockогород
Вот как раз колхозить огород тут предлагаешь именно ты. Мое предложение (будь такая возможность) - воспользоваться проработанной теорией (а если говорить про другие ЯП то и практикой).
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643668
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stanilarYuRockделается элементарно ...
В сферическом примере - да. На практике будут разные ситуации типа преждевременного завершения ожидающего потокаНу это если сделать "две функции", как предлагаешь ты. А если мониторить отписку читателей - проблемы такой не будет.
Все, конечно, больше и больше усложняется. Именно это наверно и нужно автору - усложнить задачу. Получается, так.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643669
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stanilarВот как раз колхозить огород тут предлагаешь именно ты. Мое предложение (будь такая возможность) - воспользоваться проработанной теорией (а если говорить про другие ЯП то и практикой).Мой колхозный огород - прост, понятен и нагляден как 3 копейки.
В отличие от "теории".
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643672
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockМой колхозный огород - прост, понятен и нагляден как 3 копейки.

А еще он ничем не отличается от моего. В очередь ведь будут добавляться что-то типа колбэков(событий)?
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643673
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockА если мониторить отписку читателей - проблемы такой не будет.

В реактивности, аналогично, можно отписаться от сервера событий. Речь то, на самом деле, про наличие проработанных компонент.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643675
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stanilarYuRockМой колхозный огород - прост, понятен и нагляден как 3 копейки.

А еще он ничем не отличается от моего. В очередь ведь будут добавляться что-то типа колбэков(событий)?Нет, конечно. Просто указатель на память под результат (если нужно).
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643679
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockНет, конечно.
А как сообщить ждущему потоку, что данные пришли? Он будет сам, в цикле, проверять наличие данных?
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643751
stanilar,
Код: 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.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
program LiTh;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  PJob = ^TJob;
  TJob = class
    private
      fRef    :Integer;
      fCount  :Integer;
      fData   :Pointer;
      fResult :Pointer;
      eOk     :Pointer;
      eWait   :Pointer;
      eRef    :Pointer;
      class procedure Signal(aEvent: Pointer); static; inline;
      class procedure Wait(aEvent: Pointer); static; inline;
    public
      constructor Create;
      destructor  Destroy; override;
      function  IncRef:Integer;
      procedure DecRef;
      function  Send(aData :Pointer):Pointer;
      function  Next(var aData :Pointer; var aResult :PPointer):Boolean;
  end;

constructor TJob.Create;
begin
  eOk := System.MonitorSupport.NewWaitObject();
  eRef := System.MonitorSupport.NewWaitObject();
  eWait := System.MonitorSupport.NewWaitObject();
end;

destructor TJob.Destroy;
begin
  while True do begin
    Wait(eRef);
    if fRef = 1 then Send(nil)
      else if fRef = 0 then Break;
  end;
  System.MonitorSupport.FreeWaitObject(eWait);
  System.MonitorSupport.FreeWaitObject(eRef);
  System.MonitorSupport.FreeWaitObject(eOk);
  inherited;
end;

class procedure TJob.Wait(aEvent: Pointer);
begin
  System.MonitorSupport.WaitOrSignalObject(nil, aEvent, INFINITE);
end;

class procedure TJob.Signal(aEvent: Pointer);
begin
  System.MonitorSupport.WaitOrSignalObject(aEvent, nil, 0);
end;


function TJob.IncRef:Integer;
begin
 Result := AtomicIncrement(fRef);
end;

procedure TJob.DecRef;
begin
  AtomicDecrement(fRef);
  Signal(eRef);
end;

function TJob.Send(aData: Pointer): Pointer;
begin
  System.TMonitor.Enter(Self);        // становимся в очередь
  fData := aData;                     // данные задания
  Signal(eWait);                      // сигнал о задании
  if Assigned(aData) then begin
    Wait(eOk);                        // ожидание выполнения
    Result := fResult;                // забераем результат
WriteLn(IntToStr(NativeInt(Result))); // Debug
  end;
  System.TMonitor.Exit(Self);         // уходим из очереди
end;

function TJob.Next(var aData: Pointer; var aResult: PPointer):Boolean;
begin
  if fCount>0 then Signal(eOk);       // сигнал о выполнении
  Wait(eWait);                        // ожидание задания
  aData := fData;                     // какие данные
  aResult := @fResult;                // куда результат
  Result := Assigned(aData);
  Inc(fCount);
end;

function BeginThread(ThreadFunc: TThreadFunc; Parameter: Pointer): NativeInt;
{$IFDEF POSIX}
 var d : NativeUInt; begin Result := System.BeginThread(nil, ThreadFunc, Parameter, d); end;
{$ENDIF POSIX}
{$IFDEF MSWINDOWS}
 var d : Cardinal;  begin Result := System.BeginThread(nil, 0, ThreadFunc, Parameter, 0, d); end;
{$ENDIF MSWINDOWS}


procedure Thread1(Job:TJob);
var
 aData   : Pointer;
 aResult : PPointer;
begin
 Job.IncRef;
   while Job.Next(aData, aResult)     // данные поступили
     do aResult^ := PByte(aData)+1;   // работаем
 Job.DecRef;
end;

procedure Thread234(Job:TJob);
var
 i      : Integer;
 Data   : Pointer;
 Result : Pointer;
begin
 i := Job.IncRef * 100;
   for i := i to i+3 do begin
     Data := Pointer(i);
     Result := Job.Send(Data);        // делегируем
     Sleep(Random(100));
   end;
 Job.DecRef;
end;
                                      // // // // // // //
var
  i:Integer;
  Job : TJob;
begin
  Job := TJob.Create;
    BeginThread(@Thread1, Job);
    for i := 2 to 4 do BeginThread(@Thread234, Job);
  Job.Free;
  Writeln('Fin');
end.

...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643787
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stanilarYuRockНет, конечно.
А как сообщить ждущему потоку, что данные пришли? Он будет сам, в цикле, проверять наличие данных?Взвести событие, сигнализирующее об этом.
Не коллбэк, а событие, которого ожидающий поток ждет и спит при этом, без всяких циклов.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643849
Thread
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
YuRockstanilarпропущено...

А как сообщить ждущему потоку, что данные пришли? Он будет сам, в цикле, ш8проверять наличие данных?Взвести событие, сигнализирующее об этом.
Не коллбэк, а событие, которого ожидающий поток ждет и спит при этом, без всяких циклов.

Вот сейчас как раз сижу, разбираюсь с TEvent
Штудирую конец этой статьи: Потоки и методы их синхронизаций в Delphi
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643853
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Thread,

Хватит TSimpleEvent. TEvent - именованные - для междупроцессных взаимодействий.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643950
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
истопник в кедах

Ну не цикл конечно, тем более что способ реализации WaitOrSignalObject выходит не только за рамки моей компетенции но и интересов(подразумевается, что реализация могла быть через цикл). Но смысл дискуссии был немного про другое. Вот ты, вместо того, чтоб передать коллбэк из потока в общий список, передал коллбэк реализации списка в поток. И что, теперь коллбэк перестал быть коллбэком?

P/S/ Не радует меня справка любимой среды

WaitOrSignalObject helpEmbarcadero Technologies does not currently have any additional information. Please help us document this topic by using the Discussion page!
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643980
stanilar
я это, адресатом ошибся. Пример ТС-у был - в ответ на его картинку. Ну и типа кроссплатформа.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
 //system.pas 
  PMonitorSupport = ^TMonitorSupport;
  TMonitorSupport = record
    // Obtain a synchronization object - usually an auto-reset event or semaphore
    NewSyncObject: function: Pointer;
    // Free the synchronization object obtained from NewSyncObject
    FreeSyncObject: procedure (SyncObject: Pointer);
    // Obtain a wait object - usually an auto-reset event or semaphore - these should be cached
    NewWaitObject: function: Pointer;
    // Return the wait object from NewWaitObject back to the cache
    FreeWaitObject: procedure (WaitObject: Pointer);
    // Wait for either a SyncObject or WaitObject or signal an object
    // o WaitOrSignalObject(nil, Obj, Timeout); - Wait for <Timeout> time or until <Obj> is signaled
    // o WaitOrSignalObject(Obj, nil, 0); - Signal <Obj> and return. Timeout and WaitObject params ignored.
    WaitOrSignalObject: function (SignalObject, WaitObject: Pointer; Timeout: Cardinal): Cardinal;
  end;


Если про коллбэк - то вопрос в том, в контексте какого потока он будет выполнен и как это реализовать.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643989
Thread
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я еще во многом не разобрался, но вот в процессе поиска попалась мне очень настораживающая статья: WaitForSingleObject. Why you should never use it. . Там как раз обыгрывается моя ситуация с COM объектами в потоке и как следствие скрытые окна и возможные блокировки. Но я еще не всё осознал.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643997
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Thread,

1. Статью не читал. Эта функция - основа всех основ.
2. Если твои COM-объекты окна любят выбрасывать - то, конечно, в доп. потоке реализовать работу будет сложно, мягко говоря.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643998
Threadнастораживающая статья: WaitForSingleObject. Why you should never use it. . а ещё https://www.transl-gunsmoker.ru/2010/03/msgwaitformultipleobjects.html и тогда
Код: pascal
1.
while true do 'Think carefully about whether a thread is the right solution to the problem';
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39644480
Thread
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо всем, кто откликнулся!

Я решил (как мне кажется) проблему через два TEvent'a. Ниже выкладываю код диаграмму работы.
Бросьте пожалуйста взгляд, всё ли в порядке.


TThread1 = class(TThread)
Код: 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.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
type
   TThread1 = class(TThread)
   private
      FBusy                         : boolean;

      FRequest                      : string;
      FAnswer                       : string;

      FWaitRequestEvent             : TEvent;
      FOnRequestProcessedEvent      : TEvent;
   public
      procedure  AfterConstruction(); override;
      destructor Destroy(); override;
      procedure Execute(); override;

      procedure SyncExecute(const ARequest: string; var AAnswer: string);
   public
      property Busy: boolean read FBusy;
   end;


procedure TThread1.AfterConstruction();
begin
   inherited;

   FWaitRequestEvent:=TEvent.Create(nil, True, False, CreateGUID());

   FBusy := false;
end;


destructor TThread1.Destroy();
begin
   FWaitRequestEvent.Free();
   
   inherited;
end;


procedure TThread1.SyncExecute(const ARequest: string; var AAnswer: string);
var
   RequestProcessedEvent   : TEvent;
   WaitResult              : TWaitResult;
begin
   FRequest:=ARequest;
   FAnswer:='';

   FWaitRequestEvent.ResetEvent();

   RequestProcessedEvent := TEvent.Create(nil, True, False, CreateGUID());
   try
      FOnRequestProcessedEvent:=RequestProcessedEvent;
      FWaitRequestEvent.SetEvent();

      WaitResult := FOnRequestProcessedEvent.WaitFor(INFINITE);
   finally
      FOnRequestProcessedEvent := nil;
      FreeAndNil(RequestProcessedEvent);
   end;

   AAnswer:= FAnswer;
end;


procedure ___ProcessMessages();
var
   lpMsg    : TMsg;
begin
   while PeekMessage(lpMsg,0,0,0,PM_REMOVE) do
   begin
      TranslateMessage(lpMsg);
      DispatchMessage(lpMsg);
   end;
end;


procedure TThread1.Execute();
var
   ComObjects              : TMyComObjects;
   WaitResult              : TWaitResult;
begin
   CoInitialize(nil);
   try
      ComObjects := TMyComObjects.Create();
      try
         while not Terminated do
         begin
            WaitResult := FWaitRequestEvent.WaitFor(50); //50ms is not too long

            if WaitResult = wrSignaled then
            begin
               FBusy:=true;
               try
                  FWaitRequestEvent.ResetEvent();

                  Sleep(50); //50ms for preparing of FOnRequestProcessedEvent

                  try
                     ComObjects.XYZ(FRequest, FAnswer);
                  
			finally
                     FBusy:=false;
                  end;

                  if Assigned(FOnRequestProcessedEvent) then
                  begin
                     FOnRequestProcessedEvent.SetEvent();
                     FOnRequestProcessedEvent:=nil;
                  end;
               finally
                  FBusy:=false;
               end;
            end;
         end;
      finally
         if Assigned(FOnRequestProcessedEvent) then
         begin
            FOnRequestProcessedEvent.SetEvent();
            FOnRequestProcessedEvent:=nil;
         end;

         FreeAndNil(ComObjects);
         ___ProcessMessages(); // без этого вылетает Access Violation при уничтожении thread'a
      end;
   finally
      CoUnInitialize();
   end;
end;


...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39644488
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Thread
Код: pascal
1.
CoInitialize


"Не читал...", замени на CoInitializeEx(nil, COINIT_MULTITHREADED)
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39644498
Thread
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: pascal
1.
CoInitializeEx(nil, COINIT_MULTITHREADED) 


спасибо, не знал.


Я долго не мог взять в толк насчет TEvent'a, пока не догадался, что их нужно два. Я ведь прав?

(скопирую картинку с предыдущей страницы, а то она бесполезно никем не будет увидена)
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39644510
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и вариант от меня: \.m./ :)
Два потока. Первый запускает второй и получает от него ответ в своем контексте.

Код: 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.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
    Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, wcthread;

type

    { TForm1 }

    TForm1 = class(TForm)
        Memo1: TMemo;
        Task1: TTask;
        Task2: TTask;
        WCThread1: TWCThread;
        WCThread2: TWCThread;
        procedure FormCreate(Sender: TObject);
        procedure Task1Execute(const Sender: TTask; const Msg: Word; var Param: Variant);
        procedure Task1Finish(const Sender: TTask; const Msg: Word; const Param: Variant);
        procedure Task2Finish(const Sender: TTask; const Msg: Word; const Param: Variant);
        procedure TaskMessage(const Sender: TTask; const Msg: Word; const Param: Variant);
        procedure Task2Execute(const Sender: TTask; const Msg: Word; var Param: Variant);
    private
        procedure AddToLog(const AText: string);
    public

    end;

var
    Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
    Memo1.Clear;
    AddToLog(Format('MainThread: %d', [GetCurrentThreadId]));
    Task1.Start; // запуск первого потока
end;

procedure TForm1.AddToLog(const AText: string);
begin
    Memo1.Lines.Add(AText);
end;

procedure TForm1.Task1Execute(const Sender: TTask; const Msg: Word; var Param: Variant);
begin
    // первый поток
    Sender.PostMessage(1, Format('Task1Execute thread: %d', [GetCurrentThreadId]));
    Sender.WaitMs(100);
    Task2.Start(Sender.Parent); // запуск второго потока с указанием потока-владельца (первый поток)
end;

procedure TForm1.Task1Finish(const Sender: TTask; const Msg: Word; const Param: Variant);
begin
    // выполняется в главном потоке
    Sender.PostMessage(1, Format('Task1Finish thread: %d', [GetCurrentThreadId]));
end;

procedure TForm1.Task2Execute(const Sender: TTask; const Msg: Word; var Param: Variant);
begin
    // второй поток
    Sender.PostMessage(1, Format('Task2Execute thread: %d', [GetCurrentThreadId]));
    Sender.WaitMs(1000);
end;

procedure TForm1.Task2Finish(const Sender: TTask; const Msg: Word; const Param: Variant);
begin
    // выполняется в контексте первого потока
    Sender.PostMessage(1, Format('Task2Finish thread: %d', [GetCurrentThreadId]));
end;

procedure TForm1.TaskMessage(const Sender: TTask; const Msg: Word; const Param: Variant);
begin
    // выполняется в завимимости от... то в главном потоке, то в первом (здесь некрасивый код, нельзя в УИ лезть из других потоков)
    case Msg of
        1: AddToLog(Param);
    end;
end;

end.


Task1 из WCThread1, соответственно Task2 из WCThread2.
Лог:

MainThread: 13736 основной поток
Task1Execute thread: 10176 первый поток
Task1Finish thread: 13736 основной поток
Task2Execute thread: 1188 второй поток
Task2Finish thread: 10176 первый поток
...
Рейтинг: 0 / 0
78 сообщений из 78, показаны все 4 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как организовать ожидание пока Thread не отработает задание
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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