自定义线程行为不端

Gui*_*ill 3 delphi multithreading delphi-xe3

鉴于以下课程:

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;
Run Code Online (Sandbox Code Playgroud)

当主窗体InstanceVar := EventTitle.Create自动调用时,Thread应该到达方法CreateSprite,奇怪的是没有发生.我无法理解为什么该方法没有被执行.该应用程序的主要形式仍然可以正常工作,但它似乎EventTitle.Execute突然停止甚至无法启动.它也可能是错误的实现.这是我的第一个MultiThreading试用版,然后抱歉任何不一致.谁能看到我做错了什么?

Dav*_*nan 5

这里有一些明显的问题.我不确定修复它们会解决你的问题,但我不会感到惊讶:

  1. Execute必须声明您的方法才能override运行它.这解释了您报告的行为.
  2. 必须声明析构函数才能override运行它.请注意,您实现GEvent.DestroyGEvent该类未声明析构函数.所以问题中的代码不能编译.
  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;
Run Code Online (Sandbox Code Playgroud)

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

  • 这个问题与线程无关.它纯粹是与虚拟方法解析相关的语言问题.您不希望在有关线程的文章中找到所讨论的内容.你会在语言指南中找到它.好读. (3认同)