-1

我创建了一个从 TThread 类派生的新类,在构造函数上我调用“inherited Create(True);”,然后调用“Resume()”,因为我已经覆盖了 Execute() 调用,现在我想调用 Execute( ) (再次运行线程)而不破坏类实例,所以我在新类中有一个名为“myRestart()”的函数,它调用“继承的 Create(True);” 并使我能够再次调用“Resume()”并且线程再次工作。

我的问题是,这是一种安全的做法吗?如果我有这个类的多个实例,它也会起作用吗?或者有更好的方法吗?

谢谢

4

2 回答 2

4

不要到处做这样的事情。如果您希望线程类中的过程/函数运行不止一次,请从 Execute 覆盖中的 while() 循环调用它们,并向线程发出信号以在顶部使用合适的同步对象、信号量或事件来运行代码,说:

TmyThread.Execute;
begin
  while true do
  begin
    someEvent.waitFor(INFINITE);
    if terminated then exit;
    doMyProcedure(params);
    doOtherStuff;
  end;
end;
于 2012-11-26T14:03:13.650 回答
-1

我认为您必须显示您的重启代码?因为据我所知,如果线程完成它的 Execute 过程,那么它在操作系统中的状态将更改为 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.

要使用此代码,只需创建一个工作人员,然后创建一些作业实例并将它们添加到 NotFinished 列表中。Worker 会一一执行所有作业。要重新启动作业,只需从已完成列表中提取它并再次将其添加到未完成。

请记住,您必须继承您的作业并覆盖 ExecuteJob 过程。

于 2012-11-26T10:19:21.723 回答