multithreadingdelphitlistbox

Delphi asynchronous write to TListBox


I want to write from multiple threads/processes to a TListBox called 'listMessages' and I have this two procedures in order to do this :

1- With adding object :

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

2- With TIdCriticalSection called 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; 

Can you tell me which is best(fast + thread safe) or show me a third way to write messages to my TListBox from my threads/processes ?


Solution

  • Neither of your options is any good. You need to use option 3!

    The point is that all access to UI controls must execute on the main thread. Use TThread.Synchronize or TThread.Queue to marshal UI code onto the main UI thread. Once you do this, the code will not need any further serialization because the very act of getting it to run on the UI thread serializes it.

    The code might look like this:

    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;
    

    In your update you state that you need to write to the list box from a different process. This cannot be achieved with any of the code in the question. You need inter-process communication (IPC) for that. Sending windows messages would be a reasonable approach to take, but there are other IPC options available. But I think that you mis-speak when you use the term process. I suspect that you don't mean process, but what you do mean, I have no idea.