Multithreading 未按预期调用TThread.Execute

Multithreading 未按预期调用TThread.Execute,multithreading,delphi,delphi-2010,Multithreading,Delphi,Delphi 2010,在我的应用程序中的一个长操作期间,我试图显示一个指示覆盖的活动(一个旋转的圆点)。为此,我创建了一个带有TImage和Imagelist的无边界透明表单,我试图在主线程繁忙时在线程中更新它 我遇到的问题是,冗长的操作似乎没有被我的线程“打断”。在冗长的操作开始之前,thread.Execute函数循环几次,然后在操作完成时再次循环 似乎线程由于某种原因而被饿死了。我试图提高它的优先级,但看不到任何效果 有没有人有类似的经验可以分享,或者甚至是一个解决方案 线程函数的源代码 procedure

在我的应用程序中的一个长操作期间,我试图显示一个指示覆盖的活动(一个旋转的圆点)。为此,我创建了一个带有TImage和Imagelist的无边界透明表单,我试图在主线程繁忙时在线程中更新它

我遇到的问题是,冗长的操作似乎没有被我的线程“打断”。在冗长的操作开始之前,thread.Execute函数循环几次,然后在操作完成时再次循环

似乎线程由于某种原因而被饿死了。我试图提高它的优先级,但看不到任何效果

有没有人有类似的经验可以分享,或者甚至是一个解决方案


线程函数的源代码

procedure TIndicatorThread.Execute;
begin
  inherited;
  while(not Terminated) do
    begin
      fDlg.fCurindex := (fDlg.fCurindex+1) mod 12;
      Synchronize(UpdateImage);
      Application.ProcessMessages;
      sleep(80);
    end;
    Synchronize(fDlg.close);
    Synchronize(fDlg.Free);
end;
主线程

begin
[...]
myThread := TIndicatorThread.Create;
mythread.Resume;

Init_SomeUIRelatedstuff;
Application.ProcessMessages;

DoLengthyOperation; 

mythread.Terminate;

您正在Synchronize()中完成大部分线程工作,这会将工作委托回主线程。如果主线程的冗长操作没有处理来自消息队列的新消息,则Synchronize()必须等待。这就是为什么在运行冗长的操作时,线程不会执行任何操作

您的代码是如何有效使用线程的一个糟糕示例。相反,您应该在线程中执行冗长的操作本身,并让主线程在线程运行时处理UI更新,例如:

procedure TWorkThread.Execute; 
begin 
  DoLengthyOperation;  
end; 

begin 
  ...
  Init_SomeUIRelatedstuff; 
  Application.ProcessMessages; 

  myThread := TWorkThread.Create(False);
  while WaitForSingleObject(myThread.Handle, 80) = WAIT_TIMEOUT do
  begin 
    fDlg.fCurindex := (fDlg.fCurindex+1) mod 12; 
    UpdateImage; 
    Application.ProcessMessages; 
  end; 
  mythread.Free;

  fDlg.Close; 
  fDlg.Free;

  ...
end;

您正在Synchronize()中完成大部分线程工作,这会将工作委托回主线程。如果主线程的冗长操作没有处理来自消息队列的新消息,则Synchronize()必须等待。这就是为什么在运行冗长的操作时,线程不会执行任何操作

您的代码是如何有效使用线程的一个糟糕示例。相反,您应该在线程中执行冗长的操作本身,并让主线程在线程运行时处理UI更新,例如:

procedure TWorkThread.Execute; 
begin 
  DoLengthyOperation;  
end; 

begin 
  ...
  Init_SomeUIRelatedstuff; 
  Application.ProcessMessages; 

  myThread := TWorkThread.Create(False);
  while WaitForSingleObject(myThread.Handle, 80) = WAIT_TIMEOUT do
  begin 
    fDlg.fCurindex := (fDlg.fCurindex+1) mod 12; 
    UpdateImage; 
    Application.ProcessMessages; 
  end; 
  mythread.Free;

  fDlg.Close; 
  fDlg.Free;

  ...
end;

我使用了可以显示动画GIF()的GIF图像组件, 我在计时器里放了一个很长的操作 在单独的线程中执行)


简单但有效。

我使用了可以显示动画GIF()的GIF图像组件, 我在计时器里放了一个很长的操作 在单独的线程中执行)


简单但有效。

谢谢你的解释。谢谢你的解释。这也是我第一次想到的,但我不能在我的项目中使用第三方组件(因为政治)。这也是我第一次想到的,但我不能在我的项目中使用第三方组件(因为政治)