如何通过线程执行工作负载来动画化微调 [英] How to animate a spinner while performing a workload via threading

查看:166
本文介绍了如何通过线程执行工作负载来动画化微调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Delphi xe5应用程序使用多个线程在iOS设备上遇到麻烦。我的目标是执行一些工作(SQL查询),而有一个TAniIndicator正在旋转。我已经尝试使用Applicaiton.ProcessMessages(),但是如果有时旋转,则不会使旋转器平滑地加载。



这是我现在的一个btn.OnClick的代码

  begin 
如果btnLogin.Text ='登录',然后开始
aThread:= TMyThread.Create(True);
aThread.FreeOnTerminate = = true;
aThread.Start;
而Mode1 = 0 do begin
Form_Login.LoadSpinnerFrame.visible:= True;
Form_Login.LoadSpinner.Visible:= True;
Form_Login.LoadSpinner.Enabled:= True;
// Application.ProcessMessages;
结束
Form_Login.LoadSpinnerFrame.visible:= False;
Form_Login.LoadSpinner.Visible:= False;
Form_Login.LoadSpinner.Enabled:= False
btnLogin.Text:='注销';
aThread.Destroy;
end else begin
btnLogin.Text:='Login';
结束

这里是thread.execute方法的代码

  procedure TMyThread.Execute; 
begin
Form_login.mode1:= 0;
睡眠(5000);
Form_login.mode1:= 1;
结束

我正在一直能够让线程执行的点,但是微调从不显示。
如何在一些微调器在加载工作期间进行动画处理?如何执行某些工作?



谢谢
使用Delphi xe5开发一个iOS应用程序。



更新:
好​​的,使用下面的代码从LU RD更新...但是,我注意到增加了滞后。当在调试器下运行时,应用程序将在以下行之间挂起:

  Thread.DoTerminate; 
Thread.FFinished:= True;

在System.Classes单元的ThreadProc函数下



任何线索为什么?或者我可以做什么来防止增加5秒滞后?谢谢

解决方案

在开始线程之前启用您的微调。



为您的线程定义一个 OnTerminate 方法,您可以在其中禁用微调框。



在线程中执行您的工作准备好了, OnTerminate 负责删除微调器。



注意:没有必要明确释放线程,因为 FreeOnTerminate 是真的。

  begin 
if btnLogin.Text ='Login'然后开始
Form_Login.LoadSpinnerFrame.visible:= True;
Form_Login.LoadSpinner.Visible:= True;
Form_Login.LoadSpinner.Enabled:= True;
btnLogin.Enabled:= False;
aThread:= TMyThread.Create(True);
aThread.FreeOnTerminate:= true;
aThread.OnTerminate:= Self.WorkIsDone;
aThread.Start;
end
else begin
btnLogin.Text:='Login';
结束

procedure TYourForm.WorkIsDone(Sender:TObject);
begin
Form_Login.LoadSpinnerFrame.visible:= False;
Form_Login.LoadSpinner.Visible:= False;
Form_Login.LoadSpinner.Enabled:= False;
btnLogin.Text:='注销';
btnLogin.Enabled:= True;
结束

程序TMyThread.Execute;
begin
//让你的工作
结束;

这里重要的是程序流是事件驱动的。不需要轮询,可能会耗尽CPU周期并使GUI无响应。


I am having troubles using multiple threads in my Delphi xe5 application for an iOS device. My goal is to perform 'some work' (SQL query), while having a TAniIndicator is spinning. I have tried using Applicaiton.ProcessMessages(), but that doesn't keep the spinner loading smoothly, if spinning at all sometimes.

Here is my current code for a btn.OnClick

begin
  if btnLogin.Text = 'Login' then begin
    aThread := TMyThread.Create(True);
    aThread.FreeOnTerminate := true;
    aThread.Start;
      while Mode1 = 0 do begin
          Form_Login.LoadSpinnerFrame.visible := True;
          Form_Login.LoadSpinner.Visible := True;
          Form_Login.LoadSpinner.Enabled := True;
         // Application.ProcessMessages;
       end;
    Form_Login.LoadSpinnerFrame.visible := False;
    Form_Login.LoadSpinner.Visible := False;
    Form_Login.LoadSpinner.Enabled := False;
    btnLogin.Text := 'Logout';
    aThread.Destroy;
  end else begin
    btnLogin.Text := 'Login';
  end; 

Here is code for the thread.execute method

procedure TMyThread.Execute;
begin
  Form_login.mode1 := 0;
    Sleep(5000);
  Form_login.mode1 := 1;
end;

I am at a point where I can consistently get the Thread to execute, but the spinner never shows. How Can I perform 'some work', while a spinner is animating during the work load?

Thank you, Using Delphi xe5 for developing an iOS application.

UPDATED: Okay, so updated using the code below from LU RD... It works, however, I've noticed added lag. When ran under the debugger, the application hangs between the lines:

Thread.DoTerminate;
Thread.FFinished := True;

under the ThreadProc Function of System.Classes Unit

Any clue as to why ? Or what I can do to prevent that added 5 second lag? Thank you

解决方案

Enable your spinner before starting the thread.

Define an OnTerminate method for your thread where you disable the spinner.

Do your work in the thread and when it is ready, the OnTerminate takes care of removing the spinner.

Note: There is no need to explicitly free your thread, since FreeOnTerminate is true.

begin
  if btnLogin.Text = 'Login' then begin
    Form_Login.LoadSpinnerFrame.visible := True;
    Form_Login.LoadSpinner.Visible := True;
    Form_Login.LoadSpinner.Enabled := True;
    btnLogin.Enabled := False;
    aThread := TMyThread.Create(True);
    aThread.FreeOnTerminate := true;
    aThread.OnTerminate := Self.WorkIsDone;
    aThread.Start;
  end 
  else begin
    btnLogin.Text := 'Login';
  end; 

procedure TYourForm.WorkIsDone(Sender : TObject);
begin
  Form_Login.LoadSpinnerFrame.visible := False;
  Form_Login.LoadSpinner.Visible := False;
  Form_Login.LoadSpinner.Enabled := False;
  btnLogin.Text := 'Logout';
  btnLogin.Enabled := True;
end;

procedure TMyThread.Execute;
begin
  // Make your work
end;

The important thing here is that the program flow is event driven. No polling required which can drain the CPU cycles and make the GUI unresponsive.

这篇关于如何通过线程执行工作负载来动画化微调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆