Frage

Angesichts der folgenden Klassen:

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;

Wenn das Hauptformular aufruft InstanceVar := EventTitle.Create automatisch sollte der Thread die Methode erreichen CreateSprite, was seltsamerweise nicht passiert.Ich konnte nicht verstehen, warum die Methode nicht ausgeführt wird.Die Hauptform der Anwendung funktioniert immer noch einwandfrei, aber es scheint so EventTitle.Execute stoppt abrupt oder startet gar nicht.Möglicherweise handelt es sich auch um eine Fehlimplementierung.Es ist mein erster MultiThreading-Versuch, bitte entschuldigen Sie etwaige Unstimmigkeiten.Kann jemand sehen, was ich falsch gemacht habe?

War es hilfreich?

Lösung

Hier gibt es einige offensichtliche Probleme.Ich bin mir nicht sicher, ob die Behebung Ihr Problem lösen wird, würde mich aber nicht wundern:

  1. Dein Execute Methode muss mit deklariert werden override damit es läuft.Dies erklärt das von Ihnen gemeldete Verhalten.
  2. Ihr Destruktor muss mit deklariert werden override damit es läuft.Beachten Sie, dass Sie implementieren GEvent.Destroy aber die GEvent Die Klasse deklariert keinen Destruktor.Der Code in der Frage lässt sich also nicht kompilieren.
  3. Ruf nicht an Terminate im Destruktor einer Thread-Klasse.Der Destruktor der Basisklasse TThread.Destroy beendet sich und wartet auf den Thread.Entfernen Sie den Anruf an Terminate In GEvent.Destroy.
  4. Dein Terminate Methode verbirgt sich TThread.Terminate.Das ist wirklich eine schlechte Praxis.Ich bin sicher, dass der Compiler Sie davor warnt.Sie müssen die Warnungen beachten.So wie es aussieht, hält der Destruktor Ihres Threads den Thread an und wartet dann darauf, dass er beendet wird.Sie sollten besser hoffen, dass die Ausführung des Threads bereits abgeschlossen ist, wenn Sie ihn zerstören.
  5. Es ist sinnlos, einen angehaltenen Thread zu erstellen, um ihn dann sofort fortzusetzen.Obwohl es kein wirkliches Problem gibt, das dadurch verursacht wird.
  6. Der Code in GEvent.Call ist völliger Blödsinn.Nie zuweisen Self.Sie müssen diesen Code entfernen.
  7. Alle Ihre Anrufe an Suspend sind falsch.Sie dürfen nicht anrufen Suspend.Es hat unvorhersehbare Ergebnisse.Entfernen Sie die Anrufe an Suspend.

Ein wiederholter Fehler, den Sie gemacht haben, ist das Auslassen von override.Dieses Schlüsselwort wird verwendet, um eine virtuelle Methode zu überschreiben.Im Fall der Execute Methode und Destruktor sind virtuelle Methoden, die von einer Basisklasse aufgerufen werden.Wenn Sie also die virtuelle Methode nicht überschreiben, führen Sie lediglich eine neue Methode in der abgeleiteten Klasse ein.Und wenn die Basisklasse die virtuelle Methode aufruft, wird Ihre neue Methode nicht ausgeführt.

Ich schlage vor, dass Sie mit diesem Code beginnen:

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;

Ich habe fast Ihren gesamten Code entfernt, aber fast alles war falsch.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top