multithreading - 自定义线程行为不当

标签 multithreading delphi delphi-xe3

给定以下类(class):

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 终止并等待线程。在 GEvent.Destroy 中删除对 Terminate 的调用。
  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;

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

关于multithreading - 自定义线程行为不当,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21050766/

相关文章:

delphi - 在 Delphi 2010 备忘录中看不到 UTF8 字符

Delphi 如何使用 RTTI 获取属性的默认值

delphi - 如何从 PAnsichar 转换为 PWidechar?

delphi - 使用自定义组件

java - 如何在Java中的多个线程之间共享公共(public)日志文件

c++ - 在没有锁的情况下设置条件变量监视器标志是否有效?

python - 线程与异步网络(扭曲)Python

regex - 使用正则表达式从头开始匹配 x 字符

delphi - 让 Woll2Woll 与 Delphi 7 dbExpress 一起工作的方法?

multithreading - (Tomcat) 网络服务 : OutOfMemoryError: unable to create new native thread