简体   繁体   English

我如何等待TTimer完成?

[英]How do I wait for a TTimer to finish?

I have a TFrame (fraDisplay) with a TTimer (timAnimateDataChange). 我有一个带有TTimer(timAnimateDataChange)的TFrame(fraDisplay)。 The timer is used to control a small animation. 计时器用于控制小动画。 In the form containing the frame I want to have a method that does something like this: 在包含框架的表单中,我希望有一个类似这样的方法:

procedure TForm.DoStuff;
begin
   DoSomeLogicStuff;
   fraDisplay.AnimateResult;
   WaitForAnimationToFinish;
   DoSomeOtherLogicStuff;
   fraDisplay.AnimateEndResult;
   WaitForAnimationToFinish;
   fraDisplay.Finalize;
end;

The animations are basically redraws of a TImage32, timed by a timer. 动画基本上是由TImage32重绘,由计时器计时。 The timer will disable it self when finished, and the frame has a boolean property called AnimationRunning which will be set to false when the animation is finished. 完成时计时器将自动禁用它,并且帧具有名为AnimationRunning的布尔属性,当动画结束时,该属性将设置为false。

There are no threads or anything like that to complicate or help matters. 没有任何线索或类似的东西可以使事情变得复杂或有帮助。

The question is, how do I implement the WaitForAnimationToFinish-method? 问题是,我如何实现WaitForAnimationToFinish方法?

(Btw, this is not a good solution: (顺便说一句,这不是一个好的解决方案:

procedure TForm.WaitForAnimationToFinish;
begin
  repeat 
    Application.ProcessMessages;
  until not fraDisplay.AnimationRunning;
end;

since the timer won't fire while the method is running :-( ) 因为在方法运行时计时器不会触发:-()

Smasher's suggestion could be implemented using Delphi 2009's anonymous methods. Smasher的建议可以使用Delphi 2009的匿名方法实现。

procedure TForm.DoStuff;
begin
  DoSomeLogicStuff;
  fraDisplay.AnimateResult.OnFinished := 
    procedure (Sender: TObject)
    begin
      DoSomeOtherLogicStuff;
      fraDisplay.AnimateEndResult.OnFinished := 
        procedure (Sender: TObject)
        begin
          fraDisplay.Finalize;
        end;
      fraDisplay.AnimateEndResult;
    end;
  fraDisplay.AnimateResult;
end;

BTW: Actually, WaitForAnimationToFinish will let OnTimer fire, since it uses windows messages that are dispatched when calling ProcessMessages. BTW:实际上,WaitForAnimationToFinish会让OnTimer激活,因为它使用在调用ProcessMessages时调度的Windows消息。 But it is a bad idea anyway since it uses lots of CPU without actually needing it. 但无论如何它都是一个坏主意,因为它使用了大量的CPU而实际上并不需要它。

当计时器禁用自身并将AnimationRunning变量设置为False ,您可以调用下一个应该执行的方法。

斯洛文尼亚的Delphi程序员只写了你正在寻找的代码 - Active Sleep

So what your timer is doing is something lengthy, on the order of several seconds? 那么你的计时器正在做什么是长时间的,大约几秒钟? That kind of long-running activity shouldn't be performed in the main GUI loop anyway. 无论如何,不​​应该在主GUI循环中执行那种长时间运行的活动。 Nor should waiting for such: 也不应该等待:

While you're waiting for the animation to finish (if you could), the rest of your application will behave like a dead program, ie it will not respond to the GUI in any way, including resizing, redrawing, closing with the X , etc. 当你等待动画完成时(如果可以的话),你的应用程序的其余部分将表现得像死程序,即它不会以任何方式响应GUI,包括调整大小,重绘,用X关闭,等等

The solution is to instead break up your DoStuff method into two; 解决方案是将DoStuff方法分解为两个; one that starts up the timer activity, and a second one that executes when the timer finishes. 一个启动计时器活动,另一个启动计时器完成。 To accomplish the latter, that timer should be calling your second method just before saying goodbye. 要完成后者,那个计时器应该在说再见之前调用你的第二种方法。

Lars has done a great job of putting together an example; 拉斯在组织榜样方面做得很好; consider this the book to go with his movie :) 考虑这本书与他的电影:)

使AnimateResults在完成后调用要调用的方法的参数。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM