2014-01-10 6 views
3

:사용자 정의 스레드 오작동

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처럼 보입니다. 그것은 잘못된 구현 일 수도 있습니다. 그것은 나의 첫번째 MultiThreading 예심이고, 그때 어떤 불일치든지 유감스럽게 생각한다. 누구든지 내가 뭘 잘못했는지 알 수 있니?

+0

OT :'Suspend'와'Resume'을 사용하지 마십시오. 컴파일러가 경고 메시지를 보냈을 때 사용되지 않습니다 ... 스레드를 즉각적으로 다시 시작하여 일시 중지 된 상태로 만들면 많은 도움이되지 않습니다. – TLama

+0

정말. 나는 아이들 스레드에'Resume'을 할 것입니다. 그것을 제거하는 중 ... – Guill

+0

아마 OmniThreadLibrary를 사용하면 TThread의 내부를 파는 것보다 더 쉬울 것입니다 –

답변

5

여기에 몇 가지 명백한 문제가 있습니다. 나는 그들이 문제를 해결할 고정 모르겠어요,하지만 난 놀라지 않을 것이다 : 그것은 실행하는 데

  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 메서드 및 소멸자의 경우에는 기본 클래스에서 호출하는 가상 메서드입니다. 따라서 가상 메서드를 재정의하지 않으면 단순히 파생 클래스에 새 메서드를 도입하는 것입니다. 기본 클래스가 가상 메서드를 호출하면 새 메서드가 실행되지 않습니다. 나는 거의 모든 코드를 제거했지만, 거의 모든 IT의 잘못이었다

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; 

:

난 당신이 코드로 시작하는 것이 좋습니다.

+0

1. 그 다음에는 좋습니다. 2.'GEvent'는 많은 자녀를 가질 것입니다; 그들 중 일부는 초기화 작업이 필요할 수 있습니다. 그러나 모든 여기의 Ok도. 삼.이 코드는'GEvent' 속성을 가진 다른 클래스를 참조합니다. 이 프로퍼티는'Call' 메쏘드로 이벤트 사이에서 바뀌지 만, 어쨌든 그 라인을 제거하려고합니다. 그리고 그것은 문제의 원인이 아닙니다. 4. 모든'Suspend' 호출이 제거되었습니다. 문제가 지속됩니다. – Guill

+0

답변이 업데이트되었습니다. 새 항목 1을 읽으십시오. –

+0

'Override'가 누락되었습니다. 일단 GEvent 클래스를 오버 라이드하면 나는 그 아이들에서 할 필요가 없다고 생각했다. Delphi의 스레딩 (Threading)에 관한 페이지에서이 컨벤션을 발견하지 못했습니다. 그들은 매우 필요합니다. 어쨌든, 고마워요. 나는 너의 대답을 받아 들일거야. 나는 아직 투표를 할 수 없다 ... – Guill