2013-05-31 5 views
-1

Delphi-v5와 스레드에서 실행되는 구성 요소 (TmFileScan - thanks Mats)를 사용하여 스레드를 정상적으로 종료 할 수 있기를 원합니다. 여기에서 많은 검색과 읽기를 한 후에 나는 그것을 끝낼 수 있었지만 중단 후 화면 정리를 처리하는 이벤트가 필요합니다. thread onterminate - 이벤트 작성에 도움이됩니다.

는 스레드에서 나는

Button1Click... 
begin 
    SearchThread.Terminate; 
end; 

응용 프로그램에서 다음

while not(Terminated) do // Iterating about a zillion times :) 
    ... 

를 ... 추가하고 그것을 잘 작동합니다. 스레드가 정상적으로 완료되면 시작되는 기존 OnReady 이벤트에서 화면을 정리합니다. 그러나 스레드가 종료 된 경우에는 OnAbort 이벤트를 구성 요소에 추가해야합니다.

누군가 해당 이벤트에 대한 코드 스 니펫을 제공해 줄 수 있습니까? 구성 요소에는 일시 중지 및 다시 시작 이벤트가 있지만 중단은 없습니다.

감사합니다.

+0

가능한 중복 [어떻게 죽일 : 당신이 this TmFileScan component를 사용하는 가정은, 그때는 OnReady 이벤트가 항상 트리거되도록 다음과 같은 수정을 제안 델파이의 스레드?] (http://stackoverflow.com/questions/4044855/how-to-kill-a-thread-in-delphi) –

+0

스레드를 종료하는 방법에 대한 아이디어가있는 것처럼 보입니다. 그래서 당신의 질문은 무엇입니까? 종결 된 깃발의 등록시에 호출 할 자신의 이벤트를 작성하는 방법? 귀하의 질문은 명확하지 않습니다. – Glenn1234

+0

스레드가 정상적으로 종료했는지 강제되었는지 확인하려면 실행시 tthread.retvalue를 다른 방식으로 설정하십시오. onterminate 이벤트에서이 값을 읽을 수 있습니다. http://www.delphipages.com/forum/showthread.php?t=209703을 참조하십시오. –

답변

3

TThread 클래스에는 OnTerminate 이벤트가 있습니다. Execute()이 종료되는지 여부와 상관없이 Execute() 종료 후에 호출되는 가상 TThread.DoTerminate() 메서드에 의해 트리거되거나 캐치되지 않는 예외를 통해 트리거됩니다. DoTerminate()을 무시하고 Terminated 속성이 True이거나 FatalException 속성이 nil이 아니고 그렇지 않으면 OnReady 이벤트를 트리거하는 경우 OnAbort 이벤트를 발생 시키십시오.

업데이트 :

TSearchThread = class(TThread) 
private 
    ... 
protected 
    ... 
    procedure DoTerminate; override; // <-- add this 
public 
    destructor Destroy; override; // <-- add this 
end; 

constructor TSearchThread.Create(Owner: TmFileScan; SubDir, Started: Boolean; 
    FilePaths, Filter: TStrings; fOnFileFound: TOnFileFoundEvent; 
    fOnReady: TOnReadyEvent); 
begin 
    inherited Create(true); 
    ... 
    ffList := TStringList.Create; // <-- add this 
    ... 
    Resume; 
end; 

// add this 
destructor TSearchThread.Destroy; 
begin 
    ffList.Free; 
    inherited Destroy; 
end; 

procedure TSearchThread.Execute; 
var 
    ... 
begin // function FindFile 
    // remove this 
    { 
    ffList:= TStringList.Create; 
    try 
    while not Terminated do 
    begin 
    } 
     for q:= 0 to ffPaths.Count - 1 do 
     begin 
     if Terminated then Break; // <-- add this 
     for n:= 0 to ffFilters.Count - 1 do 
     begin 
      if Terminated then Break; // <-- add this 
      Spec:= ffFilters[n]; 
      RFindFile(BackSlashFix(ffPaths[q])); 
     end; 
     end; 
    // remove this 
    { 
     Synchronize(Ready); // <-- remove this 
     Terminate; 
    end; 
    finally 
    ffList.Free; 
    end; 
    } 
end; 

// add this 
procedure TSearchThread.DoTerminate; 
begin 
    Synchronize(Ready); 
    inherited; 
end; 
+0

고마워,하지만 나는 똑똑하지 않다. :) 구성 요소에는 OnTerminate 또는 DoTerminate 이벤트가 없으므로 제안하는대로 코드를 작성하는 방법을 잘 모르겠습니다. 나는 전에 쓰레드를 다뤄 본 적이 없으며 내가 필요한 것을 수행 할 때만이 쓰레드를 사용하고있다. 나는 실력을 배우고 이해하는 데 시간을 할애하지 못합니다. 저는 15 년 동안 프로그래밍에 익숙하지 않았기 때문에 당분간 정상적인 작업 라인에서 사용할 수 없습니다. 그래서 코드 스 니펫을 요청했습니다. – user2373289

+0

'TmFileScan'구성 요소가 디자인 타임 구성 요소 인 경우 직접적인'TThread' 클래스 하위 클래스 일 수는 없지만 내부적으로 구현 된'TThread' 클래스가 있습니다. 이는 다시 말해서이 대답이 당신을위한 것이 아님을 의미합니다. 'TThread' 클래스의 자손으로 작업하고 있다면 적용 할 수 있습니다. 내부 스레드가있는 구성 요소 인 경우 해당 내부 'TThread'클래스를 공용으로 두거나 해당 구성 요소가 게시 된 종료 이벤트를 직접 (또는 적어도 좀 더 구체적으로 공개해야합니다.) 필요합니다. – TLama

+0

@TLama :이 질문에 그가 실제 스레드에 대한 액세스 권한을 가지고 있고 해당 스레드 코드를 이미 수정했다고 가정하면이 대답이 적용됩니다. –

관련 문제