我想从多个线程/进程写入一个名为“TListBox”的listMessages,为此我有两个过程:
1-添加对象:
procedure Log(Msg: String; Color: TColor);
begin
listMessages.Items.AddObject(Msg, Pointer(Color));
listMessages.ItemIndex := listMessages.Items.Count -1;
end;2-使用名为protectListMessages的TIdCriticalSection:
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?
发布于 2014-07-03 11:14:40
你们的选择都不是好的。你需要使用选项3!
要点是,对UI控件的所有访问都必须在主线程上执行。使用TThread.Synchronize或TThread.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选项可用。但我认为你在使用“过程”这个词时说错了话。我怀疑你不是指过程,但你的意思是,我不知道。
https://stackoverflow.com/questions/24551490
复制相似问题