我想从多个线程/进程写入一个名为“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保护列表消息 :
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写入消息?
你的选择都没有任何好处。你需要使用选项3!
要点是对 UI 控件的所有访问都必须在主线程上执行。使用TThread.Synchronize
or 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 选项。但我认为当你使用“过程”一词时,你说错了。我怀疑你不是指过程,但你的意思是什么,我不知道。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)