TThread.Execute 未按预期调用
我试图在应用程序的长时间操作期间显示指示覆盖(旋转的圆点)的活动。为此,我创建了一个带有 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;
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.
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.
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;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您正在 Synchronize() 内部完成大部分线程工作,它将工作委托回主线程。如果主线程的冗长操作没有处理消息队列中的新消息,则 Synchronize() 必须等待。这就是为什么你的线程在长时间操作运行时不执行任何操作。
您的代码是如何有效使用线程的一个糟糕示例。相反,您应该做的是在线程中执行冗长的操作本身,并让主线程在线程运行时处理 UI 更新,例如:
Your are doing the bulk of your thread work inside of Synchronize(), which delegates the work back to the main thread. If the main thread's lengthy operation is not processing new messages from the message queue, then Synchronize() has to wait. 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:
我使用了可以显示动画 GIF 的 GIF 图像组件(http://www.tolderlund.eu/delphi/),
我在计时器中放入了一个冗长的操作(
在单独的线程中执行)。
简单但有效。
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).
Simple but effective.