2012-12-25 2 views
4

나는 TMyThread라는 스레드를 가지고 있고이 같은 실행 절차를 오버라이드 : 기본 폼에서쓰레드가 끝나기 전에 어떻게 멈추게합니까?

procedure TMyThread.Execute; 
Begin 
    repeat 
    //Some Work 
    Sleep(5000); 
    //Some Work 2; 
    Sleep(5000); 
    until FActive=False 
End; 

을 나는 '내 스레드를 파괴'라는 버튼이 있습니다. 내 스레드를 파괴하고 싶지만 문제는 스레드가 작업을 마친 후에 만 ​​파괴된다는 것입니다. 작업을 끝내지도 내 실을 파기하고 싶습니다. 어떻게해야합니까?

+0

확인이 아웃 : http://stackoverflow.com/questions/4044855/how-to-kill-a-thread-in-delphi – kostas

+4

기술적으로 가능하지만, 정말 * 나쁜 생각 A *입니다. 실을 죽이지 말고 자살하라고하십시오. 올바른 해결책은 스레드가 플래그 (예 :'Terminated' 속성)를 충분히 자주 확인하도록하는 것입니다. – CodesInChaos

+4

그리고 작업자 스레드를 잠자기 상태로 만들려면 해당 시간 동안 스레드가 수신 대기 중이므로 (종료 됨) sleep을 사용하지 마십시오. 예를 들어 이벤트 및 WaitForSingleObject를 사용하십시오. http://objectmix.com/delphi/402360-tthread-sleep-terminate.html ("델파이가 setevent를 종료 할 때 검색 됨") –

답변

2

TEvent이는 예를 들어,이 문제에 해결할 수 있습니다 사용 : 난 내 스레드를 죽이고 싶다면 지금

uses SyncObjs; 
    TMyThread = class(TThread) 
     private 
     FTerminateEvent: TEvent; 
     protected 
     procedure Execute; override ; 
     public 
     constructor Create(ACreateSuspended: Boolean); overload; 
     destructor Destroy; override; 
     procedure Stop; 
     end; 
    constructor TMyThread.Create(ACreateSuspended: Boolean); 
    begin 
    FTerminateEvent := TEvent.Create(nil, True, False, 'FTerminateEvent'); 
    inherited Create(ACreateSuspended); 
    end; 

    destructor TMyThread.Destroy; 
    begin 
    FTerminateEvent.Free; 
    inherited; 
    end; 

    procedure TMyThread.Stop; 
    begin 
    Terminate; 
    FTerminateEvent.SetEvent; 
    end; 

    procedure TMyThread.Execute; 
    begin 
     while not Terminated do 
     begin 
     // do somthing interesting! 
     FTerminateEvent.WaitFor(5000); 
     end; 
    end; 

은, 내가 무엇을해야 모든 MyThread.Free를 호출하는 대신 MyThread.Stop를 호출한다.

+3

왜 Terminate –

+2

을 사용하지 않고 자신의 병렬 메커니즘을 구현하도록 선택 했습니까?이 작업을 수행하는 방법을 명확히 알기 위해서는'TThread.TerminatedSet'을 재정의하고'FTerminateEvent.SetEvent'를 호출해야합니다. 그리고'inherited Destroy'를 호출 한 후에'FTerminateEvent'를 해제해야합니다. 내 업데이트 답변을 참조하십시오. –

22

스레드의 Execute 메서드는 스레드의 Terminated 속성의 상태를 정기적으로 확인해야합니다. True이면 스레드 Execute 메서드를 종료해야합니다.

그래서, 일반적인 Execute 방법은 다음과 같습니다 스레드가 동일한 작업을 수행하는 자신의 FActive 플래그가 같은

procedure TMyThread.Execute; 
begin 
    while not Terminated do 
    DoNextPieceOfWork 
end; 

그것은 보인다. 그 문제는 TThread이 그것에 대해 모른다는 것입니다. 따라서 FActive을 없애고 대신 내장 메커니즘을 사용해야합니다.

스레드에서 Free을 호출하면 Terminate이 호출됩니다. 이는 TerminatedTrue으로 설정합니다. 그런 다음 스레드 메소드가 종료 될 때까지 기다립니다. 이는 스레드가 TerminatedTrue이고 종료 될 때 발생합니다. 그런 다음 스레드의 소멸자가 스레드를 정리하는 작업을 계속할 수 있습니다. 답변의 코드를 보면


, 더 나은 기존 Terminate 메커니즘을 사용하도록 작성된 것입니다.

type 
    TMyThread = class(TThread) 
    private 
    FTerminateEvent: TEvent; 
    protected 
    procedure Execute; override; 
    procedure TerminatedSet; override; 
    public 
    constructor Create(ACreateSuspended: Boolean); 
    destructor Destroy; override; 
    end; 

constructor TMyThread.Create(ACreateSuspended: Boolean); 
begin 
    inherited Create(ACreateSuspended); 
    FTerminateEvent := TEvent.Create(nil, True, False, ''); 
end; 

destructor TMyThread.Destroy; 
begin 
    inherited; 
    FTerminateEvent.Free; 
end; 

procedure TMyThread.TerminatedSet; 
begin 
    FTerminateEvent.SetEvent; 
end; 

procedure TMyThread.Execute; 
begin 
    while not Terminated do 
    begin 
    // do somthing interesting! 
    FTerminateEvent.WaitFor(5000); 
    end; 
end; 

는 이제 별도의 Stop 방법에 대한 필요가 없습니다. 스레드에서 Free으로 전화하면됩니다. 그런 다음 Terminate이 호출됩니다. 그런 다음 TerminatedSet이 호출됩니다. 그런 다음 이벤트가 신호됩니다. 그런 다음 Execute이 종료됩니다. 그리고 실은 사라질 수 있습니다.


그런데 나는 5000ms 타임 아웃이 가장 좋은 방법이 될 수 있다고 생각하고있다. 왜 이렇게하는지 모르겠지만, 스레드가 실행되지 않도록 조절하려고하고있는 것 같습니다. . 바쁜 루프를 피하려고합니다. 감탄할만한 일이지만, 고정 타임 아웃을 사용하는 것은 그것을 할 수있는 방법이 아닙니다. 이를 수행하는 방법은 동기화 이벤트 (일반적으로 이벤트)를 기다리는 것입니다. 그런 다음 더 많은 작업이 완료되면 이벤트가 신호로 보내고 스레드가 깨어납니다.

+0

내가 대신 FActive를 사용합니다. –

+0

David, 스레드 메서드 (작업)를 기다리는 내 스레드가 없습니다. –

+2

작업 코드는 종료를 확인해야합니다. –

1

정말이 문제를 완전히 잘못 접근하고 있습니다. 스레드가 원하는 작업 만 수행하도록 코드를 작성한 다음 스레드를 제어하기 위해 "외부에서 접근"할 필요가 없습니다. 외부에서이 스레드를 제어해야 할 필요성을 느끼고 있습니다. 원하지 않는 작업을하고 있기 때문입니다. 그렇다면 왜 처음에 그렇게하도록 코드를 작성 했습니까?

+0

나는 수면 방법을 사용하기 전에 기다려야 만합니다. –

+2

잠들기가 필요합니다. –

+2

@ user1720557 : 잘 있었고, 잠이 들었습니다. 그러나 당신이 일어나면, 다음해야 할 일에 대해 현명한 결정을하십시오. –

관련 문제