自定义线程行为不端

时间:2014-01-10 17:35:12

标签: multithreading delphi 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;

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

1 个答案:

答案 0 :(得分:5)

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

  1. 必须使用Execute声明您的override方法才能运行它。这解释了您报告的行为。
  2. 必须使用override声明析构函数才能运行它。请注意,您实现了GEvent.Destroy,但GEvent类未声明析构函数。所以问题中的代码不能编译。
  3. 不要在线程类的析构函数中调用Terminate。基类析构函数TThread.Destroy终止并等待线程。移除Terminate中对GEvent.Destroy的号召。
  4. 您的Terminate方法会隐藏TThread.Terminate。这是非常糟糕的做法。我确信编译器会警告你这一点。你必须留意警告。因为它代表你的线程的析构函数挂起线程然后等待它完成。你最好希望线程在你销毁之前已经完成了执行。
  5. 创建暂停的线程只是为了立即恢复它是没有意义的。虽然没有真正的问题会由此造成。
  6. GEvent.Call中的代码完全是虚假的。永远不要分配给Self。您必须删除该代码。
  7. 您对Suspend的所有来电都是错误的。您不得致电Suspend。它有不可预测的结果。移除对Suspend
  8. 的来电

    您所犯的重复错误是遗漏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;
    

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