给定以下课程:

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 突然停止甚至无法启动。这也可能是错误实现。这是我第一次尝试多线程,对于任何不一致之处深表歉意。谁能看到我做错了什么吗?

有帮助吗?

解决方案

这里存在一些明显的问题。我不确定修复它们能否解决您的问题,但我不会感到惊讶:

  1. 你的 Execute 方法必须声明为 override 让它运行。这解释了您报告的行为。
  2. 你的析构函数必须声明为 override 让它运行。请注意,您实施 GEvent.Destroy 但是 GEvent 类没有声明析构函数。所以问题中的代码无法编译。
  3. 不要打电话 Terminate 在线程类的析构函数中。基类析构函数 TThread.Destroy 终止并等待线程。删除对 TerminateGEvent.Destroy.
  4. 你的 Terminate 方法隐藏 TThread.Terminate. 。这确实是很糟糕的做法。我确信编译器会警告你这一点。您必须留意警告。按照目前的情况,线程的析构函数会挂起线程,然后等待它完成。您最好希望在销毁线程时该线程已经完成执行。
  5. 创建一个挂起的线程只是为了立即恢复它是没有意义的。尽管这不会造成真正的问题。
  6. 代码在 GEvent.Call 完全是假的。从不分配给 Self. 。您必须删除该代码。
  7. 您所有的来电 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;

我已经删除了几乎所有代码,但几乎所有代码都是错误的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top