在Delphi中
通常可以用以下三种方法来实现程序的延时
即TTtimer控件
Sleep函数
GetTickCount函数
但是其精度是各不相同的
一三种方法的简单介绍
)TTtimer控件
TTtimer控件的实质是调用Windows API定时函数SetTimer和KillTimer来实现的并简化了对WM_TIMER 消息的处理过程通过设置OnTimer事件和Interval属性我们可以很方便的产生一些简单的定时事件
)Sleep函数
Sleep函数用来使程序的执行延时给定的时间值Sleep的调用形式为Sleep(milliseconds)暂停当前的进程milliseconds毫秒Sleep的实现方法其实也是调用Windows API的Sleep函数例如
sleep();//延迟毫秒
Sleep会引起程序停滞如果你延迟的时间较长的话你的程序将不能够响应延时期间的发生的其他消息所以程序看起来好像暂时死机
)GetTickCount函数
在主程序中延时为了达到延时和响应消息这两个目的GetTickCount()构成的循环就是一种广为流传的方法例如
procedure Delay(MSecs: Longint);
//延时函数MSecs单位为毫秒(千分之秒)
var
FirstTickCount Now: Longint;
begin
FirstTickCount := GetTickCount();
repeat
ApplicationProcessMessages;
Now := GetTickCount();
until (Now FirstTickCount >= MSecs) or (Now < FirstTickCount);
end;
二高精度的微妙级性能计数器(highresolution performance counter)介绍
为了比较以上方法的精度首先需要找到一个参考的定时器在这里我提供了两个参考的定时器一是用单片机每隔ms产生一个实时中断RTI作为计数器二是选用了一个高精度的微妙级性能计数器(参见 ltaspx 或者
)
)计数器的Delphi源代码
{
Ahighprecisioncounter/timerRetrievestimedifferences
downtomicrosec
QuickReference:
THPCounterinheritsfromTComponent
KeyMethods:
Start:StartsthecounterPlacethiscalljustbeforethe
codeyouwanttomeasure
Read:ReadsthecounterasastringPlacethiscalljust
afterthecodeyouwanttomeasure
ReadInt:ReadsthecounterasanIntPlacethiscalljust
afterthecodeyouwanttomeasure
}
unitHPCounter;
interface
uses
SysUtilsWinTypesWinProcsMessagesClassesGraphicsControls
FormsDialogsStdCtrlsExtCtrls;
type
TInt=TLargeInteger;
THPCounter=class(TComponent)
private
Frequency:TLargeInteger;
lpPerformanceCount:TLargeInteger;
lpPerformanceCount:TLargeInteger;
fAbout:string;
procedureSetAbout(Value:string);
{Privatedeclarations}
public
constructorCreate(AOwner:TComponent);override;
destructorDestroy;override;
procedureStart;
functionRead:string;
functionReadInt:TLargeInteger;
{Privatedeclarations}
published
propertyAbout:stringreadfAboutwriteSetAbout;
{Publisheddeclarations}
end;
procedureRegister;
implementation
procedureRegister;
begin
RegisterComponents(MAsProd[THPCounter]);
end;
constructorTHPCounterCreate(AOwner:TComponent);
begin
inheritedCreate(AOwner);
fAbout:=Version®MatsAsplundEMail:Site:;
end;
destructorTHPCounterDestroy;
begin
inheritedDestroy;
end;
functionTHPCounterRead:string;
begin
QueryPerformanceCounter(TInt((@lpPerformanceCount)^));
QueryPerformanceFrequency(TInt((@Frequency)^));
Result:=IntToStr(Round(*(lpPerformanceCount
lpPerformanceCount)/Frequency));
end;
functionTHPCounterReadInt:TLargeInteger;
begin
QueryPerformanceCounter(TInt((@lpPerformanceCount)^));
QueryPerformanceFrequency(TInt((@Frequency)^));
Result:=Round(*(lpPerformanceCount
lpPerformanceCount)/Frequency);
end;
procedureTHPCounterSetAbout(Value:string);
begin
Exit;
end;
procedureTHPCounterStart;
begin
QueryPerformanceCounter(TInt((@lpPerformanceCount)^));
end;
end
)使用方法
unitUnit;
interface
uses
WindowsMessagesSysUtilsClassesGraphicsControlsFormsDialogs
HPCounterStdCtrls;
type
TForm=class(TForm)
Button:TButton;
Edit:TEdit;
Label:TLabel;
Label:TLabel;
procedureButtonClick(Sender:TObject);
private
{Privatedeclarations}
public
{Publicdeclarations}
end;
var
Form:TForm;
implementation
{$R*DFM}
procedureTFormButtonClick(Sender:TObject);
begin
EditText:=;
ApplicationProcessMessages;
withTHPCounterCreate(Self)do
begin
Start;
//Placecodetomeasurehere
Sleep();
//Placecodetomeasurehere
EditText:=Read;
Free;
end;
end;
end
三三种方法的精度比较
为了比较采用以上种方法分别设置延时时间为msmsmsmsmsmsmsmsmsms循环次数为次得到实际的延时时间
)TTtimer控件
实际延时时间(ms)
ms
ms
ms
ms
ms
ms
ms
ms
ms
ms
)Sleep函数
ms
ms
ms
ms
ms
ms
ms
ms
ms
ms
)GetTickCount函数
ms
ms
ms
ms
ms
ms
ms
ms
ms
ms
可见相对而言Sleep的精度最高尤其是在ms以内的延时只有sleep函数才能够做到TTimer控件的定时精度最差而且稳定性不好波动很大GetTickCount函数所能实现的最短延时为ms左右稳定性相对TTimer要好一些