-
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;
我已经删除了几乎所有代码,但几乎所有代码都是错误的。
不隶属于 StackOverflow