Воссоздание TThread в классе с деривативами TThread

Я создал новый класс, производный от класса TThread, и в конструкторе я вызываю "унаследованный Create(True);", а затем вызываю "Resume()", так как я переопределил вызов Execute(), теперь я хочу вызвать Execute() (Запустите поток снова) без уничтожения экземпляра класса, поэтому у меня есть функция внутри нового класса под названием "myRestart()", которая вызывает "унаследованный Create (True);" и позволяет мне снова вызывать "Resume()" и поток снова работает.

мой вопрос, это безопасная практика? это будет работать также, если у меня есть несколько экземпляров этого класса? или есть лучший способ сделать это?

Спасибо

2 ответа

Решение

Не ходите вокруг, делая такие вещи. Если вы хотите, чтобы процедуры / функции в вашем классе потока выполнялись более одного раза, вызовите их из цикла while() в переопределении Execute и дайте сигналу потоку выполнить код с подходящим объектом синхронизации в верхней части, семафором или событием, сказать:

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

Я думаю, что вы должны показать свой код перезагрузки? Потому что, как я знаю, если поток завершит свою процедуру Execute, тогда его состояние в ОС изменится на DONE, и при вызове резюме снова только запустите этот поток, так как это функция в основном потоке, а не отдельный отдельный поток.

кстати, вы можете использовать этот пример кода для ваших нужд

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. Работник выполнит все задания по очереди. Чтобы перезапустить задание, просто извлеките его из списка "Готово" и снова добавьте в NotFinished.

помните, что вы должны наследовать свои задания и переопределять процедуру ExecuteJob.

Другие вопросы по тегам