質問

以下のクラスを考える:

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が突然停止したり、開始しないようです。それは誤解と同様に誤解をしています。それは私の最初のマルチスレッドトライアルであり、いかなる矛盾のために申し訳ありません。誰かが私が何が悪いのかを見てもらえますか?

役に立ちましたか?

解決

ここでは明らかな問題がいくつかあります。修正があなたの問題を解決することが確かではありませんが、私は驚かないでしょう:

  1. Executeメソッドは、実行するのにoverrideで宣言する必要があります。これにより、報告する動作について説明します。
  2. あなたのデストラクタは、実行するのにoverrideで宣言する必要があります。 GEvent.Destroyを実装するが、GEventクラスはデストラクタを宣言しないことに注意してください。そのため、質問のコードはコンパイルされません。
  3. スレッドクラスのデストラクタにTerminateを呼び出さないでください。基本クラスデストラクタTThread.Destroyは、スレッドを終了して待ちます。 Terminateの呼び出しを解除します。
  4. GEvent.DestroyメソッドはTerminateを隠します。それは本当に悪い練習です。私はコンパイラがこれをあなたに警告していると確信しています。あなたは警告を恐れなければなりません。スレッドのデストラクタがスレッドを中断してから、終了するのを待ちます。あなたはあなたがそれを破壊する時までにスレッドがすでに実行を終えたことを願っていました。
  5. すぐに再開するためだけに中断されたスレッドを作成するのは無意味です。それによって引き起こされるだろう本当の問題はありませんが。
  6. TThread.Terminateのコードは全く偽のボーガスです。 GEvent.Callに割り当てないでください。そのコードを削除する必要があります。
  7. Selfへのあなたの電話はすべて間違っています。 Suspendを呼び出さないでください。予測不可能な結果があります。 Suspendへの通話を削除します。
  8. あなたが行った繰り返しエラーはSuspendの省略です。そのキーワードは仮想メソッドをオーバーライドするために使用されます。 overrideメソッドとデストラクタの場合、これらは基本クラスによって呼び出された仮想メソッドです。そのため、仮想メソッドをオーバーライドしない場合は、単に派生クラスに新しいメソッドを導入しています。そして、基本クラスが仮想メソッドを呼び出すと、新しいメソッドは実行されません。

    このコードから始めることをお勧めします。

    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