문제

다음 클래스가 제공됩니다.

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;

기본 양식 호출 시 InstanceVar := EventTitle.Create 자동으로 스레드가 메소드에 도달해야 합니다. CreateSprite, 이상하게 무슨 일이 일어나지 않는 거죠.메소드가 실행되지 않는 이유를 알 수 없습니다.애플리케이션의 기본 형식은 여전히 ​​잘 작동하지만 다음과 같은 것 같습니다. EventTitle.Execute 갑자기 멈추거나 시작하지도 않습니다.구현이 잘못되었을 수도 있습니다.이것은 나의 첫 번째 멀티스레딩 시험입니다. 불일치가 있어서 죄송합니다.내가 뭘 잘못했는지 누가 볼 수 있나요?

도움이 되었습니까?

해결책

여기에는 몇 가지 명백한 문제가 있습니다.이 문제를 해결하면 문제가 해결될지 확신할 수 없지만 놀라지는 않을 것입니다.

  1. 당신의 Execute 메소드는 다음과 같이 선언되어야 합니다. override 실행되도록 합니다.이는 귀하가 신고하는 행위를 설명합니다.
  2. 소멸자는 다음과 같이 선언되어야 합니다. override 실행되도록 합니다.구현한다는 점에 유의하세요. GEvent.Destroy 하지만 GEvent 클래스는 소멸자를 선언하지 않습니다.따라서 문제의 코드는 컴파일되지 않습니다.
  3. 전화 걸지 마 Terminate 스레드 클래스의 소멸자에서.기본 클래스 소멸자 TThread.Destroy 종료하고 스레드를 기다립니다.다음 호출을 제거하세요. Terminate ~에 GEvent.Destroy.
  4. 당신의 Terminate 메소드가 숨김 TThread.Terminate.그건 정말 나쁜 습관이에요.나는 컴파일러가 이에 대해 경고한다고 확신합니다.경고에 귀를 기울여야 합니다.현재 스레드의 소멸자는 스레드를 일시 중단한 다음 완료될 때까지 기다립니다.스레드를 파괴할 때 이미 스레드 실행이 완료되기를 바라는 것이 좋습니다.
  5. 즉시 재개하기 위해 일시 ​​중단된 스레드를 만드는 것은 의미가 없습니다.그로 인해 발생할 실제 문제는 없지만.
  6. 코드는 GEvent.Call 완전히 가짜입니다.할당하지 않음 Self.해당 코드를 제거해야 합니다.
  7. 귀하의 모든 통화 Suspend 틀렸어.전화하시면 안됩니다 Suspend.예측할 수 없는 결과가 발생합니다.다음 호출을 제거하세요. Suspend.

당신이 저지른 반복적인 실수는 override.해당 키워드는 가상 메서드를 재정의하는 데 사용됩니다.의 경우 Execute 메서드 및 소멸자는 기본 클래스에서 호출되는 가상 메서드입니다.따라서 가상 메서드를 재정의하지 않으면 파생 클래스에 새 메서드를 도입하기만 하면 됩니다.그리고 기본 클래스가 가상 메서드를 호출하면 새 메서드가 실행되지 않습니다.

다음 코드로 시작하는 것이 좋습니다.

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;

거의 모든 코드를 제거했지만 거의 모든 코드가 잘못되었습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top