问题
I created a new class derived from TThread class, and on the constructor i call "inherited Create(True);", and then call "Resume()" since i have override the Execute() call, now i wanna recall the Execute() (Run the Thread Again) without destroying the class instance, so i have a function inside the new class called "myRestart()", which recalls "inherited Create(True);" and makes me able to call "Resume()" again and thread works again.
my question is, is this a safe practice? will it work also if i have multiple instances of this class? or is there a better way to do it?
thanks
回答1:
Don't go around doing things like that. If you want procedures/functions in your thread class to run more than once, call them from a while() loop in your Execute override and signal the thread to run the code with a suitable synchro object at the top, a semaphore or event, say:
TmyThread.Execute;
begin
while true do
begin
someEvent.waitFor(INFINITE);
if terminated then exit;
doMyProcedure(params);
doOtherStuff;
end;
end;
回答2:
I think you must show your Restart Code? Because as I know if the thread finish it's Execute procedure then It's state in OS will change to DONE and calling resume again only start that thread as just a function in main thread not a real separate thread.
by the way you can use this sample code for your need
unit UWorker;
interface
uses Windows, Classes, Contnrs;
type
TWorkerThread=class;
TWorkerJob=class
procedure ExecuteJob(Worker: TWorkerThread); virtual; abstract;
end;
TWorkerThread=class(TThread)
private
FFinished: TObjectList;
FNotFinished: TObjectList;
protected
procedure Execute;Override;
public
constructor Create(createSuspended: Boolean);override;
destructor Destroy; override;
public
property Finished: TObjectList read FFinished;
property NotFinished: TObjectList read FNotFinished;
end;
implementation
{ TWorkerThread }
constructor TWorkerThread.Create(createSuspended: Boolean);
begin
inherited;
FFinished := TObjectList.Create;
FNotFinished := TObjectList.Create;
end;
destructor TWorkerThread.Destroy;
begin
FFinished.Free;
FNotFinished.Free;
inherited;
end;
procedure TWorkerThread.Execute;
var
CurrentJob: TWorkerJob;
begin
while not Terminated do
begin
if FNotFinished.Count > 0 then
begin
CurrentJob := TWorkerJob(FNotFinished.Items[0]);
FNotFinished.Extract(CurrentJob);
with CurrentJob do
begin
ExecuteJob(Self);
end;
FFinished.Add(CurrentJob);
end else
begin
// pass the cpu to next thread or process
Sleep(5);
end;
end;
end;
end.
for use this code just create a worker and then create some instance of jobs and add them to NotFinished list. the Worker will execute all jobs one by one. To restart a job just extract it from Finished list and add it again to the NotFinished.
remember you must inherit your jobs and override the ExecuteJob procedure.
来源:https://stackoverflow.com/questions/13561939/recreating-a-tthread-inside-a-tthread-dervied-class