2013-05-15 3 views
2

이 스레드를 종료 할 수 없습니다. 어디서 오류를 만들었습니까?왜이 스레드가 종료되지 않습니까?

type 
    TThumbnailThread = class(TThread) 
    public 
    procedure Execute; override; 
    procedure CreateContactSheets; 
    end; 

procedure TThumbnailThread.Execute; 
begin 
    while not Terminated do 
    begin 
    CreateContactSheets; 
    Synchronize(CreateContactSheets); 
    end; 
end; 

procedure TThumbnailThread.CreateContactSheets; 
const 
    iColumns: integer = 6; 
    iRows: integer = 6; 
    iHorzontalSpace: integer = 0; 
    iVerticalSpace: integer = 0; 
    iHorzontalMargin: integer = 0; 
    iVerticalMargin: integer = 0; 
    iDrawBox: boolean = true; 
    iDrawText: boolean = True; 
    iDrawShadow: boolean = True; 
    iBackgroundColor: TColor = clWhite; 
    iBoxColor: TColor = clBlack; 
    iPageNo: Integer = -1; 
begin 
    Form1.ImageEnMView1.MIO.PrintImagesToFile(Form1.AThumbnailFilename, 80, Screen.Width, 
     Screen.Height, iColumns, Rows, iHorzontalSpace, iVerticalSpace, 
     Form1.PrintSelected1.Checked, iHorzontalMargin, iVerticalMargin, iDrawBox, iDrawText, 
     iDrawShadow, iBackgroundColor, iBoxColor, iPageNo); 
end; 

procedure TForm1.PrintToFile1Click(Sender: TObject); 
begin 
    if SavePictureDialog1.Execute then 
    begin 
    if SavePictureDialog1.FileName <> '' then 
    begin 
     Screen.Cursor := crHourGlass; 
     try 
     iFilename := SavePictureDialog1.FileName; 
     { If one thread have been started already, we don't start another. } 
     if ThumbnailThread <> nil then 
      raise Exception.Create('One thread has already been started!'); 
     AThumbnailFilename := iFilename; 
     ThumbnailThread := TThumbnailThread.Create(false); 
     ThumbnailThread.OnTerminate := TerminateTheThread; 
     finally 
     Screen.Cursor := crDefault; 
     end; 
    end; 
    end; 
end; 

procedure TForm1.Abort1Click(Sender: TObject); 
begin 
    ThumbnailThread.Terminate; 
    ProgressBar1.Position := 0; 
    Screen.Cursor := crDefault; 
end; 

procedure TForm1.TerminateTheThread; 
begin 
    Form1.ImageEnMView1.MIO.Aborting := True; 
end; 
+0

CreateContactSheets()는 VCL을 처리합니다. Execute()의 CreateContactSheets()에 대한 첫 번째 호출은 동기화에서 래핑되지 않습니다. 즉, 스레드로부터 안전하지 않습니다. –

답변

2

여기에 스레드가있을 이유는 없습니다. 동기화 된 메소드에서 모든 작업을 수행하면 실행중인 메인 스레드가 중지됩니다. 주 스레드에서 뭔가를 다시 실행하기 위해 일시 ​​중지 만하는 스레드를 만듭니다.

Form1.ImageEnMView1.MIO.PrintImagesToFileThread.Terminate 변수가 설정되었는지 확인하지 않으므로 스레드가 종료되지 않습니다. 따라서 PrintImagesToFile 플래그가 실행되지 않는 한 검사가 실행되지 않습니다. 동기화 된 메소드 (메인 스레드의 컨텍스트에서 실행 됨)를 실행 중이기 때문에 스레드가 일시 정지되었으므로 스레드는 모든 작업이 완료 될 때까지 스레드가 종료되었음을 결코 알지 못합니다.

+0

프로 시저를 중단 할 수 있도록 스레드에서 Form1.ImageEnMView1.MIO.PrintImagesToFile을 호출 할 수있는 방법이 없다는 것을 알려 주시겠습니까? – Bill

+0

@Bill 스레드를 사용하여 개념을 재고해야합니다. 모든 작업을 수행하기 위해 스레드 내부에서 양식 메소드를 호출하는 것이 매우 바람직하지 않습니다. 이렇게하면 동기화 된 스레드가 스레드를 스레드로부터 풀어줍니다. –

+2

@Bill Handover ** 모든 ** 필요한 정보를 스레드에 전달하여 백그라운드 작업을 완료합니다. 상태 정보 (예 : 진행) 만 '동기화'또는 '대기열'하고 작업 중 '종료 됨'플래그를 확인하십시오. –

관련 문제