我创建了一个派生自TThread类的新类,并在构造函数上调用“inherited Create(True);”,然后调用“Resume()”,因为我已经覆盖了Execute()调用,现在我想回忆一下执行()(再次运行线程)而不破坏类实例,所以我在新类中有一个名为“myRestart()”的函数,它回忆“继承的Create(True);”并且让我能够再次调用“Resume()”并且线程再次工作。
我的问题是,这是一种安全的做法吗?如果我有这个类的多个实例,它会工作吗?或者有更好的方法吗?
感谢
答案 0 :(得分:4)
不要四处走动。如果您希望线程类中的过程/函数多次运行,请在Execute覆盖中的while()循环中调用它们,并通过顶部的信号量或事件,通过合适的同步对象运行代码来运行代码,说:
TmyThread.Execute;
begin
while true do
begin
someEvent.waitFor(INFINITE);
if terminated then exit;
doMyProcedure(params);
doOtherStuff;
end;
end;
答案 1 :(得分:-1)
我认为您必须显示重启代码? 因为我知道线程是否完成它的执行程序然后它在操作系统中的状态将更改为DONE并再次调用resume仅将该线程作为主线程中的函数启动而不是真正的单独线程。
顺便说一下,您可以根据需要使用此示例代码
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.
使用此代码只需创建一个worker然后创建一些作业实例并将它们添加到NotFinished列表中。工人将逐个执行所有工作。 要重新启动作业,只需从完成列表中提取它,然后将其再次添加到NotFinished。
记住你必须继承你的工作并覆盖ExecuteJob程序。