简体   繁体   English

在TThread派生类中重新创建TThread

[英]Recreating a TThread Inside a TThread dervied class

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);" 我创建了一个从TThread类派生的新类,并在构造函数上调用“继承的Create(True);”,然后调用“ Resume()”,因为我已经覆盖了Execute()调用,现在我想回想Execute( )(再次运行线程)而不会破坏类实例,因此在新类中有一个名为“ myRestart()”的函数,该函数可调用“继承的Create(True);”。 and makes me able to call "Resume()" again and thread works again. 并让我能够再次调用“ Resume()”,线程再次工作。

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 谢谢

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: 如果您希望线程类中的过程/函数多次运行,请从Execute覆盖中的while()循环中调用它们,并通过最合适的同步对象,信号灯或事件来通知线程运行代码,说:

TmyThread.Execute;
begin
  while true do
  begin
    someEvent.waitFor(INFINITE);
    if terminated then exit;
    doMyProcedure(params);
    doOtherStuff;
  end;
end;

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. 因为据我所知,如果线程完成了它的执行过程,那么它在OS中的状态将更改为DONE,并且再次调用resume只能将该线程作为主线程中的一个函数启动,而不是真正的单独线程。

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. 请记住,您必须继承您的作业并覆盖ExecuteJob过程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM