Воссоздание 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.