开发者

Restart Delphi TThread that lives the entire app lifetime

开发者 https://www.devze.com 2023-03-20 15:50 出处:网络
I have created a class that derives from TThread, because I wish to do some async stuff, however to avoid having to create another class, I built the entire thing around that thread class. Not sure if

I have created a class that derives from TThread, because I wish to do some async stuff, however to avoid having to create another class, I built the entire thing around that thread class. Not sure if this is good practice or not, and if I cant get this to work, well then I suppose I have no choice but to recode..

The problem: I create the Thread on FormCreate, assign some properties, and I Free it on FormDestroy. In the Thread's constructor, I set Fr开发者_开发问答eeOnTerminate = False. When I click on a button on my Form, I Start(); the Thread. Okay, so it runs as expected, an error occurs (expected!), its being passed to my error handling event, and it appears to terminate. I then click the button again, and I get a Cannot call Start on a running or suspended thread error.

How can I finish the thread without freeing it, and enabling me to start it again?


You can't restart a thread once it is finished/terminated. In that case you should just create a new instance if the thread again like you did in FormCreate.


Catch the error in the thread, handle it there and then let the thread continue the work. To handle the error you could simply queue a method to the main thread to report the error, for example. I hope you aren't letting exceptions leave your thread Execute method.


This is the way that I implement it:

procedure TAPIRequest.DoRequest;
begin
  FBusy := True;
  Resume;
end;


procedure TAPIRequest.Execute;
begin
  inherited;

  while not Terminated do begin
    HttpError := False;

    try
      Response := HTTP.Post(URL, Params);
      ParseResponse;

    except
      HttpError := True;
    end;

    if Assigned(OnResponse) then
      OnResponse();

    FBusy := False;
    Suspend;
  end;
end;


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

var
  Form1: TForm1;
  MyThread: TMyThread;
  Event: TEvent;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Event := TEvent.Create(nil,true,false, '');
  MyThread := TMyThread.Create(False);
end;

procedure TMyThread.Execute;
begin
  while True do
    begin
      Event.WaitFor(Infinite);

      // do something

      Event.ResetEvent;
    end;
end;

procedure RestartThread;
begin
    Event.SetEvent;
// if you need check thread status, wait or run, use here 
// if Event.WaitFor(0) = ...(wrTimeout, wrSignaled)
end;
0

精彩评论

暂无评论...
验证码 换一张
取 消