Question

Étant donné les classes suivantes:

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;

Lorsque la principale forme d'appels InstanceVar := EventTitle.Create automatiquement, le Fil devrait atteindre la méthode CreateSprite, ce qui bizarrement n'est pas le cas.Je ne pouvais pas comprendre pourquoi la méthode n'est pas en cours d'exécution.La forme principale de l'application fonctionne toujours très bien, mais il semble que l' EventTitle.Execute s'arrête brusquement ou à ne pas commencer.Il pourrons peut-être misimplementation ainsi.C'est mon premier MultiThreading procès, alors désolé pour toute incohérence.N'importe qui peut voir ce que j'ai fait de mal?

Était-ce utile?

La solution

Il y a quelques problèmes évidents ici.Je ne suis pas sûr que la fixation d'eux peut résoudre votre problème, mais je ne serais pas surpris:

  1. Votre Execute la méthode doit être déclarée avec override pour qu'il fonctionne.C'est ce qui explique le comportement que vous signalez.
  2. Votre destructeur doit être déclarée avec override pour qu'il fonctionne.Notez que vous mettre en œuvre GEvent.Destroy mais l' GEvent la classe de ne pas déclarer un destructeur.Donc le code en question ne compile pas.
  3. Ne pas appeler Terminate dans le destructeur d'une classe thread.Le destructeur de la classe de base TThread.Destroy s'arrête et attend que le thread.Supprimer l'appel à Terminate dans GEvent.Destroy.
  4. Votre Terminate méthode de cache TThread.Terminate.C'est vraiment une mauvaise pratique.Je suis sûr que le compilateur vous avertit de cela.Vous devez tenir compte des avertissements.Comme il est de votre fil est destructeur suspend le thread et attend qu'elle se termine.Vous feriez mieux d'espérer que le thread a déjà fini son exécution par le temps de vous détruire.
  5. Il est inutile de créer un thread suspendu pour aussitôt reprendre.Bien qu'il n'y a pas de réel problème causé par que.
  6. Le code de la GEvent.Call est totalement bidon.Ne jamais céder à Self.Vous devez supprimer ce code.
  7. Tous vos appels Suspend sont mauvais.Vous ne devez pas appeler Suspend.Il a des résultats imprévisibles.Supprimer les appels à Suspend.

Une répétition de l'erreur que vous avez fait est l'omission de override.Ce mot clé est utilisé pour remplacer une méthode virtuelle.Dans le cas de la Execute méthode, et le destructeur, ce sont des méthodes virtuelles appelé par une classe de base.En tant que tel, si vous ne remplacent pas la méthode virtuelle, vous êtes tout simplement l'introduction d'une nouvelle méthode dans la classe dérivée.Et quand la classe de base des appels à la méthode virtuelle, votre nouvelle méthode ne s'exécutera pas.

Je vous suggère de commencer avec ce code:

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;

J'ai supprimé la quasi totalité de votre code, mais presque toutes il a eu tort.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top