简体   繁体   English

TThread.Execute没有按预期方式被调用

[英]TThread.Execute is not called as expected

I am trying to display an activity indicating overlay (a spinning circle of dots) during a lengthy operation in my application. 我试图在我的应用程序中进行长时间操作时显示一个活动,该活动指示覆盖(点的旋转的圆)。 For this, i created a borderless transparent form with a TImage and an Imagelist, which i sought to update in a thread during the time the main thread is busy. 为此,我创建了一个带有TImage和Imagelist的无边界透明表单,我试图在主线程忙时在一个线程中进行更新。

The problem i encountered is that the lengthy operation does not seem to get 'interupted' by my thread. 我遇到的问题是,冗长的操作似乎并没有被我的线程“中断”。 The thread.Execute function loops a few times before the lengthy operation starts, and then again when the operation is finished. thread.Execute函数在冗长的操作开始之前循环几次,然后在操作结束时再次循环。

It seems as if the thread is starved for some reason. 似乎线程由于某种原因而饥饿。 I tried to raise it's priority, but could not see any effect. 我试图提高它的优先级,但是看不到任何效果。

Does anyone have similar experiences to share, or maybe even a solution? 有没有人有类似的经验可以分享,甚至可以解决?


Source code of thread function 线程功能的源代码

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;

main thread 主线

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

Init_SomeUIRelatedstuff;
Application.ProcessMessages;

DoLengthyOperation; 

mythread.Terminate;

Your are doing the bulk of your thread work inside of Synchronize(), which delegates the work back to the main thread. 您正在Synchronize()内完成线程的大部分工作,该工作将工作委派回主线程。 If the main thread's lengthy operation is not processing new messages from the message queue, then Synchronize() has to wait. 如果主线程的冗长操作没有处理消息队列中的新消息,则Synchronize()必须等待。 That is why your thread does not do anything while the lengthy operation is running. 这就是为什么长时间运行操作时线程不执行任何操作的原因。

Your code is a poor example of how to use a thread effectively. 您的代码是如何有效使用线程的糟糕示例。 What you should have done instead is perform the lengthy operation itself in the thread, and let the main thread handle the UI updates while the thread is running, eg: 相反,您应该做的是在线程本身中执行冗长的操作,并让主线程在线程运行时处理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;

I used GIF image component that can show animated GIFs ( http://www.tolderlund.eu/delphi/ ), and I put a lengthy operation inside a timer (which executes in separate thread). 我使用了可以显示动画GIF的GIF图像组件( http://www.tolderlund.eu/delphi/ ),并且将一个冗长的操作放入了一个计时器(在单独的线程中执行)。

Simple but effective. 简单但有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 TThread.Execute 中调用 TDataModule 方法 - Call a TDataModule method in TThread.Execute 在 TThread.Execute 中处理异常以使其不可中断 - Handling exceptions in TThread.Execute to make it uninterruptible “错误下载URL:”在TThread.Execute中使用TDownloadUrl - “Error downloading URL: ” Using TDownloadUrl in a TThread.Execute 在TThread.Execute中加入无限循环是不好的做法? - Is it considered bad practice to put an infinite loop inside of TThread.Execute? 在TThread执行中引发异常? - Raising Exception in TThread Execute? TThread 的重载执行,与之前的声明不同 - Overload Execute of TThread, differs from previous declaration TThread.FinishThreadExecution的目的是什么,什么时候被调用? - What is the purpose of TThread.FinishThreadExecution, and when is it called? TThread和COM-“未调用CoInitialize”,尽管在构造函数中已调用CoInitialize - TThread and COM - “CoInitialize has not been called”, although CoInitialize is called in the constructor 在 C++ Builder 中,如何在“TThread”中执行 function? - In C++ Builder, how to execute a function inside a `TThread`? 我可以将Delphi TThread.Synchronize()本地移动到VCL表单以从主线程或工作线程调用吗? - Can I move Delphi TThread.Synchronize() locally to a VCL form to be called from both a main or worker thread?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM