Delphi асинхронная запись в TListBox

Я хочу писать из нескольких потоков / процессов в TListBox с именем 'listMessages', и у меня есть две процедуры для этого:

1- С добавлением объекта:

procedure Log(Msg: String; Color: TColor);
begin
  listMessages.Items.AddObject(Msg, Pointer(Color));
  listMessages.ItemIndex := listMessages.Items.Count -1;
end;

2 - С помощью TIdCriticalSection, который называется protectListMessages:

procedure TMainForm.safelyLogMessage(mess : String);
begin
  protectlistMessages.Enter;
  try
    listMessages.Items.Add(mess);
    listMessages.ItemIndex := listMessages.Items.Count -1;
  finally
    protectListMessages.Leave;
  end;
end; 

Можете ли вы сказать мне, что лучше (быстрый + потокобезопасный) или показать мне третий способ писать сообщения в мой TListBox из моих потоков / процессов?

1 ответ

Решение

Ни один из ваших вариантов ничего хорошего. Вам нужно использовать вариант 3!

Дело в том, что весь доступ к элементам управления пользовательского интерфейса должен выполняться в основном потоке. использование TThread.Synchronize или же TThread.Queue маршалировать код пользовательского интерфейса в основной поток пользовательского интерфейса. После того, как вы это сделаете, коду больше не понадобится сериализация, потому что сам процесс его запуска в потоке пользовательского интерфейса сериализует его.

Код может выглядеть так:

procedure TMainForm.Log(const Msg: string; const Color: TColor);
var
  Proc: TThreadProcedure;
begin
  Proc :=
    procedure
    begin
      ListBox1.AddItem(Msg, Pointer(Color));
      ListBox1.ItemIndex := ListBox1.Count-1;
    end;

  if GetCurrentThreadId = MainThreadID then
    Proc()
  else
    TThread.Queue(nil, Proc);
end;

В своем обновлении вы утверждаете, что вам нужно написать в список из другого процесса. Этого нельзя достичь с помощью любого кода в вопросе. Для этого вам необходимо межпроцессное взаимодействие (IPC). Отправка сообщений Windows была бы разумным подходом, но есть и другие доступные варианты IPC. Но я думаю, что вы неправильно говорите, когда используете термин "процесс". Я подозреваю, что вы не имеете в виду процесс, но что вы имеете в виду, я понятия не имею.

Другие вопросы по тегам