Delphi异步写入TListBox

时间:2014-07-03 10:40:53

标签: multithreading delphi tlistbox

我想从多个线程/进程写入名为'listMessages'的TListBox,为了做到这一点,我有两个步骤:

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 个答案:

答案 0 :(得分:3)

您的选择都没有任何好处。你需要使用选项3!

重点是所有对UI控件的访问都必须在主线程上执行。使用TThread.SynchronizeTThread.Queue将UI代码封送到主UI线程中。一旦你这样做,代码将不需要任何进一步的序列化,因为让它在UI线程上运行的行为将它序列化。

代码可能如下所示:

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选项可用。但是我认为你在使用术语过程时会说错话。我怀疑你不是指进程,但你的意思是,我不知道。