【问题标题】:TThread.Execute is not called as expectedTThread.Execute 未按预期调用
【发布时间】:2010-09-02 10:08:08
【问题描述】:

我试图在我的应用程序的长时间操作期间显示一个指示覆盖(一个旋转的圆点)的活动。为此,我创建了一个带有 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;

【问题讨论】:

    标签: multithreading delphi delphi-2010


    【解决方案1】:

    您正在 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;
    

    【讨论】:

    • 感谢您的解释。
    【解决方案2】:

    我使用了可以显示动画 GIF 的 GIF 图片组件 (http://www.tolderlund.eu/delphi/), 我在一个计时器内做了一个冗长的操作(它 在单独的线程中执行)。

    简单但有效。

    【讨论】:

    • 这也是我最先想到的,但我不能在我的项目中使用第三方组件(因为政治)
    猜你喜欢
    • 1970-01-01
    • 2014-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-02
    • 2022-01-11
    相关资源
    最近更新 更多