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