Пользовательский поток ведет себя неправильно
-
22-12-2019 - |
Вопрос
Учитывая следующие классы:
type
GEvent = class(TThread)
public
procedure Terminate;
procedure Call(Event : GEvent);
constructor Create;
procedure Execute; Override;
end;
TDirection = (DUp, DRight, DDown, DLeft);
EventTitle = class(GEvent)
private
Index : Integer;
Sprite : CSprite;
Terminate : Boolean;
procedure CreateSprite;
procedure MoveCursor(Direction : TDirection);
procedure RefreshCursor;
constructor Create;
destructor Destroy;
public
procedure Execute;
end;
implementation
{ GEvent }
procedure GEvent.Call(Event: GEvent);
begin
Suspend;
// inherited Terminate;
Self := GEvent(Event.ClassType.Create);
end;
constructor GEvent.Create;
begin
inherited Create(True);
end;
destructor GEvent.Destroy;
begin
Terminate;
inherited;
end;
procedure GEvent.Execute;
begin
// inherited;
end;
procedure GEvent.Terminate;
begin
Suspend;
inherited;
end;
{ EventTitle }
constructor EventTitle.Create;
begin
inherited;
Resume;
end;
procedure EventTitle.CreateSprite;
begin
Showmessage('anything');
end;
destructor EventTitle.Destroy;
begin
inherited;
end;
procedure EventTitle.Execute;
begin
inherited;
Synchronize(CreateSprite);
Index := 0; {
while not Terminated do
begin
if GISystem.System.Input.Trigger(KUp) then
MoveCursor(DUp);
if GISystem.System.Input.Trigger(KDown) then
MoveCursor(DDown);
end; }
end;
Когда вызывается основная форма InstanceVar := EventTitle.Create
автоматически поток должен достичь метода CreateSprite
, чего странно не происходит.Я не мог понять, почему метод не выполняется.Основная форма приложения по-прежнему работает нормально, но похоже, что EventTitle.Execute
резко останавливается или даже не запускается.Это может быть и неправильная реализация.Это мое первое испытание многопоточности, прошу прощения за несоответствия.Может ли кто-нибудь увидеть, что я сделал не так?
Решение
Здесь есть некоторые очевидные проблемы.Я не уверен, что их исправление решит вашу проблему, но я бы не удивился:
- Твой
Execute
метод должен быть объявлен с помощьюoverride
чтобы оно работало.Это объясняет поведение, о котором вы сообщаете. - Ваш деструктор должен быть объявлен с помощью
override
чтобы оно работало.Обратите внимание, что вы реализуетеGEvent.Destroy
ноGEvent
класс не объявляет деструктор.Таким образом, код в вопросе не компилируется. - Не звони
Terminate
в деструкторе класса потока.Деструктор базового классаTThread.Destroy
завершается и ждет потока.Удалить вызов наTerminate
вGEvent.Destroy
. - Твой
Terminate
метод скрываетTThread.Terminate
.Это действительно плохая практика.Я уверен, что компилятор вас об этом предупреждает.Вы должны прислушаться к предупреждениям.В нынешнем виде деструктор вашего потока приостанавливает поток, а затем ждет его завершения.Вам лучше надеяться, что поток уже завершит выполнение к моменту его уничтожения. - Бессмысленно создавать приостановленный поток только для того, чтобы немедленно возобновить его.Хотя никакой реальной проблемы из-за этого не будет.
- Код в
GEvent.Call
является совершенно фальшивым.Никогда не назначайтеSelf
.Вы должны удалить этот код. - Все ваши звонки на
Suspend
не правы.Вы не должны звонитьSuspend
.Оно имеет непредсказуемые результаты.Удалить звонки наSuspend
.
Повторная ошибка, которую вы допустили, заключается в пропуске override
.Это ключевое слово используется для переопределения виртуального метода.В случае Execute
метод и деструктор — это виртуальные методы, вызываемые базовым классом.Таким образом, если вы не переопределяете виртуальный метод, вы просто вводите новый метод в производный класс.И когда базовый класс вызывает виртуальный метод, ваш новый метод не будет выполнен.
Я предлагаю вам начать с этого кода:
type
EventTitle = class(TThread)
private
procedure DoSomething;
public
constructor Create;
procedure Execute; override;
end;
implementation
constructor EventTitle.Create;
begin
inherited Create(False);
end;
procedure EventTitle.DoSomething;
begin
ShowMessage('anything');
end;
procedure EventTitle.Execute;
begin
Synchronize(DoSomething);
end;
Я удалил почти весь ваш код, но почти весь он был неверным.