powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Параметризированный TThread.Queue
9 сообщений из 9, страница 1 из 1
Параметризированный TThread.Queue
    #39541998
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это замечательно, что есть TThread.Queue
Но каким образом передать туда параметры

В качестве теста использую такую конструкцию. И надеюсь, что refernce делает свою копию данных

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
procedure ProcessPicture(Value: Integer);
begin
  Value := 100500;
    TThread.Queue(nil, procedure
    begin
      MainForm.Caption := IntToStr(Value);
    end);
  Value := 500;
end;

procedure Test;
begin
  TThread.CreateAnonymousThread(procedure
  begin
    ProcessPicture(0);
  end).Start;
end;



Данным тестом я надеюсь получить значение 100500, как некое локальное
Но нет, в Caption выводится 500. Т.е. по факту параметр не только не сохраняется, но и используется грязное значение из стека
Тогда как правильно передать параметр?
Что если это составной параметр: структура или экземпляр класса?

У нас есть 2 варианта функции:
Код: pascal
1.
2.
3.
4.
5.
TThreadMethod = procedure of object;
TThreadProcedure = reference to procedure;

class procedure Queue(const AThread: TThread; AMethod: TThreadMethod);
class procedure Queue(AThread: TThread; AThreadProc: TThreadProcedure); 



Какие варианты решения я вижу.
Вариант 1:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
type
  TMyParams = object
    ...
    procedure MainThreadProcess;
  end;
  PMyParams = ^TMyParams;

procedure Enqueue;
var
  Params: PMyParams;
begin
  New(Params);
  ...
  TThread.Queue(nil, Params.MainThreadProcess);
end;

procedure TMyParams.MainThreadProcess;
begin
  ...
  Dispose(@Self);
end;



Чем плох такой вариант решения. Тем, что у Thread есть функция RemoveQueuedEvents
Так вот этот функция удалит сообщения из очереди, но Dispose (или Free) передаваемым параметрам вызвано не будет. Что мягко говоря приведёт к утечкам памяти.

Второй вариант жёстче. Reference to procedure является интерфейсом с методом Invoke. Т.е. я могу унаследоваться от TInterfacedObject, реализовать метод Invoke и всё это упаковывать в TThreadProcedure. Но это слишком трешово на мой взгляд.

А как это сделать цивилизованно?
...
Рейтинг: 0 / 0
Параметризированный TThread.Queue
    #39542011
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUТогда как правильно передать параметр?Не изменять его. Или попробовать, по типу JavaScript обернуть в замыкание
SOFT FOR YOU
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
procedure ProcessPicture(Value: Integer);
begin
  Value := 100500;
  (procedure(AVal: Integer)
  begin
    TThread.Queue(nil, procedure
    begin
      MainForm.Caption := IntToStr(AVal);
    end);
  end)(Value)
  Value := 500;
end;
...
Рейтинг: 0 / 0
Параметризированный TThread.Queue
    #39542022
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOU,

А тебе точно нужно передавать значение асинхронно ? Ну и как вариант - сделай локальную переменную, присвой ей значение и её уже используй. И не меняй, пока Queue не отработает.
...
Рейтинг: 0 / 0
Параметризированный TThread.Queue
    #39542030
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

Толковое решение
Благодарю!
...
Рейтинг: 0 / 0
Параметризированный TThread.Queue
    #39542075
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Объясните, пожалуйста, момент


http://docwiki.embarcadero.com/Libraries/XE5/en/System.Classes.TThread.Queue
System.Classes.TThread.Queue
Asynchronously executes a method call within the main thread.

Тогда почему я сразу попадаю в первую точку останова, а не во вторую?
...
Рейтинг: 0 / 0
Параметризированный TThread.Queue
    #39542088
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Квейд,

Если Queue вызывается из главного потока, то функция не кладётся в очередь, а выполняется сразу
...
Рейтинг: 0 / 0
Параметризированный TThread.Queue
    #39542097
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUЕсли Queue вызывается из главного потока, то функция не кладётся в очередь, а выполняется сразуWarning: Do not call Queue from within the main thread. This can cause an infinite loop.
...
Рейтинг: 0 / 0
Параметризированный TThread.Queue
    #39542098
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вообще - самая полезная функция для синхронизация с основным потоком. У нас плотно используется в RichEditControl для обновления из потоков, в том числе с нарезкой потока с использонием WaitForMultipleObjects. А то тут некоторые панику поднимали, что такое сделать нельзя...
...
Рейтинг: 0 / 0
Параметризированный TThread.Queue
    #39542363
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUКвейд,

Если Queue вызывается из главного потока, то функция не кладётся в очередь, а выполняется сразу
Спасибо. Я решил, что Queue даже из главного потока выполнится отложенно. Надо читать справку до конца :)
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Параметризированный TThread.Queue
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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