【问题标题】:how to make delphi wait 30sec then continue如何让delphi等待30秒然后继续
【发布时间】:2014-03-02 09:48:32
【问题描述】:

我正在尝试创建一个无限循环,但我希望循环每 30 秒运行一次。循环将开始。发生了一堆 if 语句,并且一些信息将被更改。然后循环必须暂停 30 秒,然后循环将重新开始。这必须永远持续下去。

我正在寻找一种方法来暂停循环 30 秒然后继续。任何好的建议将不胜感激。

编辑 #1

程序根据日期和时间显示“特殊”信息:随着时间的变化,信息也会发生变化:06:00 = 数学; 07:30 = 生物学。该程序还会显示距离下一堂课开始的时间。因此程序需要不断地运行来更新时间,以便准确地知道现在是哪个周期以及距离下一个周期还有多少时间。

编辑 #2

我想放入“刷新”以便脚本我希望脚本在设定的时间间隔内被调用,这样它就不会持续运行并吃掉内存。此间隔必须为 30 秒。

【问题讨论】:

  • 问题不完整。 GUI 应用程序还是控制台应用程序?桌面还是服务?主线程还是工作线程?你需要能够取消吗?除非您提供这些详细信息,否则答案是睡眠。
  • 这将在后台运行。 vcl 表单应用程序。暂停时间是恒定的。可以停止“等待”的唯一原因是循环停止时。
  • 使用将Interval 设置为 30000 的计时器。每个计时器事件调用都是您的循环部分。因此,您没有循环,而是每 n 毫秒调用一次的方法,直到您禁用计时器
  • GUI 的意义何在?当程序“等待”时,GUI 会做什么?为什么不给我们详细信息?

标签: multithreading delphi wait


【解决方案1】:

根据您提供的更多详细信息的更新,我想我会使用带有计时器的单个线程来提供 pulse 来驱动更新。

将计时器间隔设置为您希望 GUI 更新发生的任何速率。例如,您可能需要每分钟两次的刷新率,在这种情况下,将计时器间隔设置为30*1000

每当计时器触发时,使用当前系统时间计算出您需要显示的信息,然后显示该信息。

请注意,此答案不会告诉您如何等待 30 秒并继续。但是,我怀疑这是解决您的实际问题的最简单方法。

您不想阻止您的程序,因为这会阻止 UI 响应。它会阻止您与 UI 交互并阻止 UI 绘制自身。在 GUI 程序中,您不能在主线程中阻塞。您应该只阻塞后台线程。但是线程增加了不必要的复杂性。你不想阻止。你不想等待。您只需要定期更新即可。一个计时器。

【讨论】:

    【解决方案2】:

    如果您有阻塞 GUI 的代码,您可以使用后台线程和事件来提供非阻塞计时器。

    创建一个新的 Forms 应用程序并在您的表单上放置一个 TMemo 组件。 此示例将在您的TMemo 中添加一个包含当前时间的新行。

    主要形式:

    unit u_frm_main;
    
    interface
    
    uses
      u_workthread,
      SysUtils,
      Windows,
      Forms,
      SyncObjs, Classes, Controls, StdCtrls;
    
    type
      TForm1 = class(TForm)
        Memo1: TMemo;
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        { Private declarations }
        Worker : TWorkThread;
        procedure ShowData;
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm1.ShowData;
    begin
     // do whatever you need to do here... 
     // show current time in memo
     Memo1.Lines.Add(FormatDateTime('HH:NN:SS', Now));
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
     // create our worker thread and start it
     Worker := TWorkThread.Create(3, ShowData);
     Worker.Start;
    end;
    
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
     // signal our worker thread that we are done here
     Worker.ThreadEvent.SetEvent;
     // terminate and wait
     Worker.Terminate;
     Worker.WaitFor;
    end;
    
    end.
    

    工作线程:

    unit u_workthread;
    
    interface
    
    uses
      SysUtils,
      SyncObjs,
      Classes;
    
    type
      TWorkProc = procedure of object;
    
      TWorkThread = class(TThread)
      private
        { Private declarations }
        Counter   : Integer;
        FTimeout  : Integer;
        FEventProc: TWorkProc;
        procedure DoWork;
      protected
        procedure Execute; override;
      public
        ThreadEvent : TEvent;
        constructor Create(TimeoutSeconds : Integer; EventProc: TWorkProc ); // timeout in seconds
        destructor Destroy; override;
      end;
    
    implementation
    
    procedure TWorkThread.DoWork;
    begin
     // put your GUI blocking code in here. Make sure you never call GUI elements from this procedure
     //DoSomeLongCalculation();
    end;
    
    procedure TWorkThread.Execute;
    begin
     Counter := 0;
     while not Terminated do
      begin
       if ThreadEvent.WaitFor(FTimeout) = wrTimeout then
        begin 
         DoWork;
         // now inform our main Thread that we have data
         Synchronize(FEventProc);
        end;
       else
        // ThreadEvent has been signaled, exit our loop
        Break;
      end;
    end;
    
    constructor TWorkThread.Create(TimeoutSeconds : Integer; EventProc: TWorkProc);
    begin
     ThreadEvent := TEvent.Create(nil, True, False, '');
     // Convert to milliseconds
     FTimeout := TimeoutSeconds * 1000;
     FEventProc:= EventProc;
     // call inherited constructor with CreateSuspended as True
     inherited Create(True);
    end;
    
    destructor TWorkThread.Destroy;
    begin
     ThreadEvent.Free;
     inherited;
    end;
    
    
    end.
    

    【讨论】:

      猜你喜欢
      • 2010-12-16
      • 1970-01-01
      • 1970-01-01
      • 2021-09-21
      • 2016-09-13
      • 1970-01-01
      • 1970-01-01
      • 2018-05-19
      • 2017-12-18
      相关资源
      最近更新 更多