Pergunta

Dadas as seguintes classes:

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 o formulário principal chama InstanceVar := EventTitle.Create automaticamente o Thread deve chegar ao método CreateSprite, o que estranhamente não está acontecendo.Não consegui entender por que o método não está sendo executado.A forma principal do aplicativo ainda funciona bem, mas parece que o EventTitle.Execute pára abruptamente ou até mesmo não inicia.Também pode ser uma má implementação.É meu primeiro teste MultiThreading, então desculpe qualquer inconsistência.Alguém pode ver o que eu fiz de errado?

Foi útil?

Solução

Existem alguns problemas óbvios aqui.Não tenho certeza se corrigi-los resolverá seu problema, mas não ficaria surpreso:

  1. Seu Execute o método deve ser declarado com override para que ele funcione.Isso explica o comportamento que você denuncia.
  2. Seu destruidor deve ser declarado com override para que ele funcione.Observe que você implementa GEvent.Destroy mas o GEvent classe não declara um destruidor.Portanto o código da pergunta não compila.
  3. Não ligue Terminate no destruidor de uma classe de thread.O destruidor da classe base TThread.Destroy termina e aguarda o thread.Remova a chamada para Terminate em GEvent.Destroy.
  4. Seu Terminate método esconde TThread.Terminate.Essa é uma prática muito ruim.Tenho certeza que o compilador avisa sobre isso.Você deve prestar atenção aos avisos.Da forma como está, o destruidor do seu thread suspende o thread e espera que ele termine.É melhor você torcer para que o thread já tenha terminado de ser executado no momento em que você o destrói.
  5. Não faz sentido criar um thread suspenso apenas para retomá-lo imediatamente.Embora não haja nenhum problema real que será causado por isso.
  6. O código em GEvent.Call é totalmente falso.Nunca atribua a Self.Você deve remover esse código.
  7. Todas as suas chamadas para Suspend está errado.Você não deve ligar Suspend.Tem resultados imprevisíveis.Remova as chamadas para Suspend.

Um erro repetido que você cometeu foi a omissão de override.Essa palavra-chave é usada para substituir um método virtual.No caso do Execute método e o destruidor, são métodos virtuais chamados por uma classe base.Dessa forma, se você não substituir o método virtual, estará simplesmente introduzindo um novo método na classe derivada.E quando a classe base chama o método virtual, seu novo método não será executado.

Sugiro que você comece com este código:

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;

Retirei quase todo o seu código, mas quase tudo estava errado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top