我试图做一个无限循环,但我希望循环每30秒运行。 循环将开始。 if语句发生,一些信息的一串将被改变。 然后循环必须暂停30秒,然后循环将再次启动。 这必须永远持续下去。
我正在寻找一种方式来暂停 30秒的循环,然后继续。 任何好的建议将不胜感激。
编辑 #1
该方案显示基于日期和时间的“特殊”的信息:随着时间的改变信息改变:06:00 =数学; 07:30 =生物学。 该方案还显示你离开,直到下一节课开始时间。 因此,该程序需要持续运行,从而它知道到底是什么时期,它是和多少时间留到下一期更新时间。
编辑 #2
我想提出一个“刷新”,使剧本我想,这样它不会持续运行和吃RAM中的脚本在设置的时间间隔被调用。 这个间隔必须是30秒。
如果你有一些代码块的图形用户界面,你可以使用一个后台线程和事件提供非阻塞计时器。
创建一个新的窗体应用程序,并把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.
根据您的更新,提供更多的细节,我想我会用一个单独的线程与定时器提供脉冲驱动的更新。
设置计时器的时间间隔是什么速度你想更新到GUI的发生。 比如,也许两次一分钟的刷新率是你想要的,在这种情况下,设置定时间隔30*1000
。
当计时器火灾,使用当前的系统时间来解决,你需要显示的信息,然后显示这些信息。
请注意,这个答案并不能告诉你如何等待30秒,然后继续。 不过,我怀疑这是你的实际问题,最简单的解决。
你不想阻止你的计划,因为这将阻止UI响应。 它会阻止你能够与UI交互,并从能够绘制自己停止UI。 在GUI程序,你不能在主线程阻塞。 您应该只阻止后台线程。 但是,线程增加复杂性,这只是不必要的。 你不想阻止。 你不想等待。 你只需要有规律的脉冲来驱动更新。 计时器。