Delphi 为什么';这个线程不会终止吗?

Delphi 为什么';这个线程不会终止吗?,delphi,delphi-2010,Delphi,Delphi 2010,我无法使此线程终止。我哪里出错了 type TThumbnailThread = class(TThread) public procedure Execute; override; procedure CreateContactSheets; end; procedure TThumbnailThread.Execute; begin while not Terminated do begin CreateContactSheets;

我无法使此线程终止。我哪里出错了

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;
类型
TThumbnailThread=class(TThread)
公众的
程序执行;推翻
程序表;
结束;
程序TTThread.Execute;
开始
虽然没有终止
开始
创建联系表;
同步(创建联系人表);
结束;
结束;
程序TThumbnailThread.CreateContactSheets;
常数
iColumns:integer=6;
iRows:整数=6;
iHorzontalSpace:整数=0;
iVerticalSpace:整数=0;
iHorzontalMargin:整数=0;
iVerticalMargin:整数=0;
iDrawBox:boolean=true;
iDrawText:boolean=True;
iDrawShadow:boolean=True;
iBackgroundColor:TColor=clWhite;
iBoxColor:TColor=clBlack;
iPageNo:Integer=-1;
开始
Form1.ImageEnMView1.MIO.PrintImagesToFile(Form1.AThumbnailFilename,80,Screen.Width,
屏幕高度、图标列、行、iHorzontalSpace、iVerticalSpace、,
Form1.PrintSelected 1.Checked、iHorzontalMargin、iVerticalMargin、iDrawBox、iDrawText、,
iDrawShadow、iBackgroundColor、iBoxColor、iPageNo);
结束;
程序TForm1.PrintToFile1点击(发送方:ToObject);
开始
如果SavePictureDialog1
开始
如果保存PictureDialog1.FileName“”,则
开始
Screen.Cursor:=crHourGlass;
尝试
iFilename:=SavePictureDialog1.FileName;
{如果一个线程已经启动,我们不会启动另一个。}
如果ThumbnailThread为零,则
引发异常。创建('一个线程已经启动!');
AThumbnailFilename:=iFilename;
ThumbnailThread:=TThumbnailThread.Create(false);
ThumbnailThread.OnTerminate:=TerminateThread;
最后
Screen.Cursor:=crDefault;
结束;
结束;
结束;
结束;
过程TForm1.abort1单击(发送方:TObject);
开始
ThumbnailThread.终止;
ProgressBar1.位置:=0;
Screen.Cursor:=crDefault;
结束;
程序TForm1.TerminateTheThread;
开始
Form1.ImageEnMView1.MIO.Aborting:=真;
结束;

这里绝对没有理由有线程。您在一个同步方法中完成所有工作,该方法在主线程运行时停止主线程。您正在创建一个线程,它什么也不做,只是暂停自己以在主线程中运行某些内容


您的线程没有终止,因为
Form1.ImageEnMView1.MIO.PrintImagesToFile
无法检查
thread.Terminate
变量是否已设置,因此只要
PrintImagesToFile
运行该标志,就不会被选中。由于线程已暂停,因为您正在运行同步方法(在主线程的上下文中运行),因此在完成所有工作之前,线程永远不会知道它已终止。

请注意,CreateContactSheets()处理VCL。Execute()中对CreateContactSheets()的第一次调用未包装在Synchronize中,即它不是线程安全的。因此,您建议我,无法在线程中调用Form1.ImageEnview1.MIO.PrintImagesToFile,因此该过程可以中止?@Bill您应该重新考虑使用线程的概念。从线程内部调用form方法来完成所有工作是一个非常糟糕的主意,而执行此同步操作将“解除”线程。@Bill将所有必要的信息交给线程以完成后台工作<代码>同步或
队列
只同步状态信息(例如进度),并在工作期间检查
终止
标志。@Bill:我告诉你,你当前的实现是在浪费时间,因为你在线程中什么都没做。所有的工作都是在主(GUI)线程中完成的。至于您是否可以告诉
ImageEnMView1.MIO
中止,我不知道,因为我不知道该控件做什么,也不知道它公开的功能,所以我无法对其进行评论。我只能回答你在这里提出的问题,这就是为什么这个线程没有终止,我已经回答了这个问题。如果您对组件有不同的问题,请将其作为新问题发布。@Ken,好的。谢谢你的帮助。我将停止我的尝试线程这一点。ImageEnMView1.MIO可以设置为中止,但所做的只是中止创建当前页面并继续创建剩余页面。我将继续与开发人员进行讨论。