Pregunta

Dadas las siguientes clases:

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;

Cuando la principal forma de llamadas InstanceVar := EventTitle.Create automáticamente el Hilo debe alcanzar el método CreateSprite, lo que, extrañamente, no está sucediendo.Yo no podía entender por qué el método no está siendo ejecutado.El formulario principal de la aplicación sigue funcionando bien, pero parece que el EventTitle.Execute se detiene abruptamente o incluso no se inician.Es maight ser misimplementation así.Es mi primer MultiThreading juicio, entonces lo siento por cualquier inconsistencia.¿Puede alguien ver lo que hice mal?

¿Fue útil?

Solución

Hay algunos problemas obvios aquí.No estoy seguro de que la fijación de ellos va a resolver tu problema, pero yo no estaría sorprendido:

  1. Su Execute el método debe ser declarada con override para que se ejecute.Esto explica el comportamiento que se informe.
  2. Su destructor debe ser declarada con override para que se ejecute.Tenga en cuenta que implementar GEvent.Destroy pero el GEvent la clase no declarar un destructor.Así el código de la pregunta no compila.
  3. No llame Terminate en el destructor de la clase thread.El destructor de la clase base TThread.Destroy termina y se espera para el hilo.Quitar la llamada a Terminate en GEvent.Destroy.
  4. Su Terminate método oculta TThread.Terminate.Que es muy mala práctica.Estoy seguro de que el compilador avisa de esto.Usted debe prestar atención a las advertencias.Tal y como está el hilo del destructor suspende el hilo y, a continuación, espera a que termine.Es mejor que la esperanza de que el hilo ya ha terminado de ejecutar en el momento de destruirlo.
  5. No tiene sentido crear un hilo suspendido solamente a reanudar de inmediato de ella.Aunque no hay ningún problema real, que serán causados por el que.
  6. El código de GEvent.Call es absolutamente falso.Nunca ceder a Self.Debe quitar ese código.
  7. Todas tus llamadas a Suspend están equivocados.Usted no debe llamar a Suspend.Tiene resultados impredecibles.Eliminar las llamadas a Suspend.

Un error repetidos que han hecho de la omisión de override.La palabra clave se utiliza para reemplazar un método virtual.En el caso de la Execute el método, y el destructor, estos son los métodos virtuales llamado por una clase base.Como tal, si no invalidar el método virtual, simplemente introduciendo un nuevo método en la clase derivada.Y cuando la clase base se llama al método virtual, el nuevo método no se ejecutará.

Le sugiero que empiece con 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;

Me he despojado de casi todo el código, pero casi todo estaba mal.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top