Domanda

Dato le seguenti classi:

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;
.

Quando la forma principale chiama InstanceVar := EventTitle.Create automaticamente il thread deve raggiungere il metodo CreateSprite, che stranamente non sta accadendo.Non riuscivo a capire perché il metodo non viene eseguito.La forma principale dell'applicazione funziona ancora bene, ma sembra che il EventTitle.Execute si ferma bruscamente o addirittura non iniziare.Essere malintendere anche.È il mio primo processo multithreading, poi mi dispiace per qualsiasi inconsistenza.Qualcuno può vedere cosa ho fatto di sbagliato?

È stato utile?

Soluzione

Ci sono alcuni problemi ovvi qui. Non sono sicuro che il fissaggio di loro risolverà il tuo problema, ma non sarei sorpreso:

    .
  1. Il tuo metodo Execute deve essere dichiarato con override per essere eseguito. Questo spiega il comportamento che noti.
  2. Il tuo distruttore deve essere dichiarato con override per essere eseguito. Si noti che implementare GEvent.Destroy ma la classe GEvent non dichiara un distruttore. Quindi il codice nella domanda non è compilato.
  3. Non chiamare Terminate nel distruttore di una classe di thread. Il distruttore di classe base TThread.Destroy termina e attende il filo. Rimuovere la chiamata su Terminate in GEvent.Destroy.
  4. Il tuo metodo Terminate nasconde TThread.Terminate. Questa è davvero cattiva pratica. Sono sicuro che il compilatore ti avverti di questo. Devi ascoltare gli avvertimenti. Mentre si trova il distruttore del tuo filo sospette il filo e quindi attende che finisca. Hai fatto meglio a sperare che il filo abbia già finito di eseguire il tempo che lo distruggi.
  5. È inutile creare un thread sospeso solo per riprenderlo immediatamente. Sebbene non ci sia un vero problema che sarà causato da quello.
  6. Il codice in GEvent.Call è assolutamente falso. Mai assegnare a Self. È necessario rimuovere quel codice.
  7. Tutte le tue chiamate a Suspend sono sbagliate. Non è necessario chiamare Suspend. Ha risultati imprevedibili. Rimuovere le chiamate a Suspend.
  8. Un errore ripetuto che hai effettuato è l'omissione di override. Quella parola chiave viene utilizzata per sovrascrivere un metodo virtuale. Nel caso del metodo Execute, e il distruttore, questi sono metodi virtuali chiamati da una classe base. Come tale, se non si sovrascrive il metodo virtuale, stai semplicemente introducendo un nuovo metodo nella classe derivata. E quando la classe base chiama il metodo virtuale, il tuo nuovo metodo non verrà eseguito.

    Ti suggerisco di iniziare con questo codice:

    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;
    
    .

    Ho spogliato quasi tutto il tuo codice, ma quasi tutto era sbagliato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top