Search code examples
multithreadingdelphidelphi-xe7

how i can execute two threads in delphi project


My project contain two procedure that perform different tasks, and i execute every thread in a timer.

My problem , is that ... when i run the project , and the timer start. the thread not work fine.

Why?

And, can I use two threads or more in the same project?

Note: I really want to use thread, I need a solution with thread.

This is my code without threads.

procedure TForm1.Timer1Timer(Sender: TObject);
var
i : integer;
begin
for i := 0 to 50 do
  begin
  Memo1.Lines.Add(IntToStr(i));
  sleep(500);
  end;
end;

procedure TForm1.Timer2Timer(Sender: TObject);
var
k : integer;
begin
for k := 0 to 50 do
  begin
  Memo2.Lines.Add(IntToStr(k));
  sleep(500);
  end;
end;

end.

With threads :

type
TThread_Timer2 = class(TThread)
protected
  procedure Execute; override;
end;

type
TThread_Timer3 = class(TThread)
protected
  procedure Execute; override;
end;

procedure TThread_Timer2.Execute;
var
i : integer;
begin
for i := 0 to 50 do
  begin
  Memo1.Lines.Add(IntToStr(i));
  sleep(500);
  end;
end;

procedure TThread_Timer3.Execute;
var
k : integer;
begin
for k := 0 to 50 do
  begin
  Memo2.Lines.Add(IntToStr(k));
  sleep(500);
  end;
end;

procedure TForm1.Timer2Timer(Sender: TObject);
var
thd : TThread_Timer2;
begin
  thd := TThread_Timer2.Create(true);
  try
    thd.FreeOnTerminate := true;
    thd.Priority := tpHighest;
  finally
    thd.Resume;
  end;
end;


procedure TForm1.Timer3Timer(Sender: TObject);
var
trhd : TThread_Timer3;
begin
  trhd := TThread_Timer3.Create(true);
  try
    trhd.FreeOnTerminate := true;
    trhd.Priority := tpHighest;
  finally
    trhd.Resume;
  end;

end;

Solution

  • Your code, with correction to do UI operations only in the main thread. It's working for me:

    TThread_Timer2 = class(TThread)
    private
      FVar: Integer;
    
      procedure UpdateMemo;
    protected
      procedure Execute; override;
    end;
    
    TThread_Timer3 = class(TThread)
    private
      FVar: Integer;
    
      procedure UpdateMemo;
    protected
      procedure Execute; override;
    end;
    
    procedure TForm1.Timer1Timer(Sender: TObject);
    var
    thd : TThread_Timer2;
    begin
      thd := TThread_Timer2.Create(true);
      try
        thd.FreeOnTerminate := true;
        thd.Priority := tpHighest;
      finally
        thd.Resume;
      end;
    end;
    
    procedure TThread_Timer2.Execute;
    var
    i : integer;
    begin
    for i := 0 to 50 do
      begin
      FVar := i;
      Synchronize(UpdateMemo);
      sleep(500);
      end;
    end;
    
    procedure TThread_Timer3.Execute;
    var
    k : integer;
    begin
    for k := 0 to 50 do
      begin
      FVar := k;
      Synchronize(UpdateMemo);
      sleep(500);
      end;
    end;
    
    procedure TForm1.Timer2Timer(Sender: TObject);
    var
    trhd : TThread_Timer3;
    begin
      trhd := TThread_Timer3.Create(true);
      try
        trhd.FreeOnTerminate := true;
        trhd.Priority := tpHighest;
      finally
        trhd.Resume;
      end;
    
    end;
    
    procedure TThread_Timer2.UpdateMemo;
    begin
      Form1.Memo1.Lines.Add(IntToStr(FVar));
    end;
    
    procedure TThread_Timer3.UpdateMemo;
    begin
      Form1.Memo2.Lines.Add(IntToStr(FVar));
    end;
    

    I didn't change anything else in your code, but have a good read on David's answer. There are remarks there you should pay attention to.