Delphi中三种延时方法及其定时精度分析

Delphi中高效实现延时与消息处理的方法 本文还有配套的精品资源,点击获取 简介:在Delphi编程中,延时函数是实现程序暂停的重要工具,广泛应用于动画、定时任务等场景。本文介绍了使用内置 Sleep 函数和自定义消息循环(如 Application.ProcessMessages )的延时方法,强调了在多线程环境下保持UI响应性和程序高效运行的重要性。对于Delphi开发者来说,理解W... 阅读详情
在Delphi中,通常可以用以下三种方法来实现程序的延时,即TTtimer控件,Sleep函数,GetTickCount函数。但是其精度是各不相同的。

一、三种方法的简单介绍

1)TTtimer控件

  TTtimer控件的实质是调用Windows API定时函数SetTimer和KillTimer来实现的,并简化了对WM_TIMER 消息的处理过程。通过设置OnTimer事件和Interval属性,我们可以很方便的产生一些简单的定时事件。

2)Sleep函数

  Sleep函数用来使程序的执行延时给定的时间值。Sleep的调用形式为Sleep(milliseconds),暂停当前的进程milliseconds毫秒。Sleep的实现方法其实也是调用Windows API的Sleep函数。例如:

sleep(1000);        //延迟1000毫秒

Sleep会引起程序停滞,如果你延迟的时间较长的话,你的程序将不能够响应延时期间的发生的其他消息,所以程序看起来好像暂时死机。

3)GetTickCount函数

  在主程序中延时,为了达到延时和响应消息这两个目的,GetTickCount()构成的循环就是一种广为流传的方法。例如:

procedure Delay(MSecs: Longint);
//延时函数,MSecs单位为毫秒(千分之1秒)
var
  FirstTickCount, Now: Longint;
begin
  FirstTickCount := GetTickCount();
  repeat
    Application.ProcessMessages;
    Now := GetTickCount();
  until (Now - FirstTickCount >= MSecs) or (Now < FirstTickCount);
end;

二、高精度的微妙级性能计数器(high-resolution performance counter)介绍

  为了比较以上方法的精度,首先需要找到一个参考的定时器。在这里,我提供了两个参考的定时器。一是用单片机每隔1.024ms产生一个实时中断RTI,作为计数器;二是选用了一个高精度的微妙级性能计数器(参见: http://msdn.microsoft.com/msdnmag/issues/04/03/HighResolutionTimer/default.aspx ,或者 http://community.youkuaiyun.com/Expert/FAQ/FAQ_Index.asp?id=200249
)

1)计数器的Delphi源代码

{ 
A  high-precision  counter/timer.  Retrieves  time  differences 
                               downto  microsec. 
Quick  Reference: 
                               THPCounter  inherits  from  TComponent. 
 
                               Key-Methods: 
                                   Start:        Starts  the  counter.  Place  this  call  just  before  the 
                                                       code  you  want  to  measure. 
 
                                   Read:          Reads  the  counter  as  a  string.  Place  this  call  just 
                                                       after  the  code  you  want  to  measure. 
 
                                   ReadInt:    Reads  the  counter  as  an  Int64.  Place  this  call  just 
                                                       after  the  code  you  want  to  measure. 
-------------------------------------------------------------------------------- 
} 
unit  HPCounter; 
 
interface 
 
uses 
   SysUtils,  WinTypes,  WinProcs,  Messages,  Classes,  Graphics,  Controls, 
   Forms,  Dialogs,  StdCtrls,  ExtCtrls; 
 
type 
   TInt64  =  TLargeInteger; 
   THPCounter  =  class(TComponent) 
private 
   Frequency:  TLargeInteger; 
   lpPerformanceCount1:  TLargeInteger; 
   lpPerformanceCount2:  TLargeInteger; 
   fAbout:  string; 
   procedure  SetAbout(Value:  string); 
   {  Private  declarations  } 
public 
   constructor  Create(AOwner:  TComponent);  override; 
   destructor  Destroy;  override; 
   procedure  Start; 
   function  Read:  string; 
   function  ReadInt:  TLargeInteger; 
   {  Private  declarations  } 
published 
   property  About:  string  read  fAbout  write  SetAbout; 
   {  Published  declarations  } 
end; 
 
 
procedure  Register; 
 
implementation 
 
procedure  Register; 
begin 
   RegisterComponents('MAs  Prod.',  [THPCounter]); 
end; 
 
constructor  THPCounter.Create(AOwner:  TComponent); 
begin 
   inherited  Create(AOwner); 
   fAbout:=  'Version  1.1,  2000&reg;  Mats  Asplund,  EMail:  masprod@telia.com,  Site:  http://go.to/masdp'; 
end; 
 
destructor  THPCounter.Destroy; 
begin 
   inherited  Destroy; 
end; 
 
function  THPCounter.Read:  string; 
begin 
   QueryPerformanceCounter(TInt64((@lpPerformanceCount2)^)); 
   QueryPerformanceFrequency(TInt64((@Frequency)^)); 
   Result:=IntToStr(Round(1000000  *  (lpPerformanceCount2  - 
                                             lpPerformanceCount1)  /  Frequency)); 
end; 
 
function  THPCounter.ReadInt:  TLargeInteger; 
begin 
   QueryPerformanceCounter(TInt64((@lpPerformanceCount2)^)); 
   QueryPerformanceFrequency(TInt64((@Frequency)^)); 
   Result:=Round(1000000  *  (lpPerformanceCount2  - 
                                             lpPerformanceCount1)  /  Frequency); 
end; 
 
procedure  THPCounter.SetAbout(Value:  string); 
begin 
   Exit; 
end; 
 
procedure  THPCounter.Start; 
begin 
   QueryPerformanceCounter(TInt64((@lpPerformanceCount1)^)); 
end; 
 
end. 

2)使用方法: 
unit  Unit1; 
 
interface 
 
uses 
   Windows,  Messages,  SysUtils,  Classes,  Graphics,  Controls,  Forms,  Dialogs, 
   HPCounter,  StdCtrls; 
 
type 
   TForm1  =  class(TForm) 
       Button1:  TButton; 
       Edit1:  TEdit; 
       Label1:  TLabel; 
       Label2:  TLabel; 
       procedure  Button1Click(Sender:  TObject); 
   private 
       {  Private  declarations  } 
   public 
       {  Public  declarations  } 
   end; 
 
var 
   Form1:  TForm1; 
 
implementation 
 
{$R  *.DFM} 
 
procedure  TForm1.Button1Click(Sender:  TObject); 
begin 
   Edit1.Text:=  ''; 
   Application.ProcessMessages; 
   with  THPCounter.Create(Self)  do 
       begin 
           Start; 
           //  Place  code  to  measure  here 
           Sleep(1000); 
           //  Place  code  to  measure  here 
           Edit1.Text:=Read; 
           Free; 
       end; 
end; 
 
end.

二、三种方法的精度比较

  为了比较,采用以上3种方法,分别设置延时时间为1ms、2ms、5ms、10ms、20ms、50ms、100ms、200ms、500ms、1000ms,循环次数为5次,得到实际的延时时间。

1)TTtimer控件

                       实际延时时间(ms)
1ms: 8.012   21.551  6.875   21.647  9.809
2ms: 9.957   20.675  14.671  11.903  20.551
5ms: 9.952   20.605  9.924   20.705  12.682
10ms:14.852  9.96    21.547  9.82    20.634
20ms:27.512  34.291  26.427  31.244  30.398
50ms:61.196  61.307  64.027  62.048  63.059
100ms:102.495 108.408 112.318 110.322 102.531
200ms:193.955 202.135 207.016 205.082 202.194
500ms:496.659 500.534 503.398 495.551 500.394
1000ms:999.699 1003.576 993.698 1004.443 995.625

2)Sleep函数

1ms: 1.895   1.895   1.896   1.897   1.898
2ms: 2.868   2.874   2.852   2.872   2.869
5ms: 5.8     5.797   5.79    5.79    5.791
10ms:10.675  10.683  10.611  10.669  10.67
20ms:20.404  20.434  20.447  20.477  20.368
50ms:50.67   50.691  50.69   50.682  50.671
100ms:100.515 100.469 100.484 100.481 100.484
200ms:200.101 200.126 199.892 200.066 200.108
500ms:499.961 499.961 499.958 499.961 499.96
1000ms:1000.034 1000.04 1000.03 1000.018 1000.029

3)GetTickCount函数

1ms: 15.54   15.596  15.527  15.566  15.838
2ms: 15.561  15.563  15.603  15.477  15.571
5ms: 15.519  15.549  15.569  15.666  15.394
10ms:15.558  15.561  15.522  15.568  15.518
20ms:31.186  31.137  31.17   31.17   31.19
50ms:62.445  62.4    63.893  60.88   62.404
100ms:109.276 109.298 109.273 109.28  109.28
200ms:203.027 203.084 203.021 203.027 203.046
500ms:499.959 499.961 499.963 499.967 499.965
1000ms:1000.023 1000.022 1000.026 1000.029 1000.021


  可见,相对而言,Sleep的精度最高,尤其是在10ms以内的延时,只有sleep函数才能够做到。TTimer控件的定时精度最差,而且稳定性不好,波动很大。GetTickCount函数所能实现的最短延时为15ms左右,稳定性相对TTimer要好一些。


Delphi中延时函数实现与DLL封装技巧 DLL是一组代码、数据和资源的集合,它被设计为当多个应用程序同时需要访问它们时,只在内存中保留一份副本。DLL的可执行代码被编译成机器码,并且它包含可被其他程序调用的函数和过程。DLL的主要特点包括:代码共享:多个程序可以共享同一个DLL中的代码,从而节省内存空间。模块化设计:开发人员可以将程序分割成多个模块,分别开发和维护。独立更新:DLL可以独立于使用它们的应用程序进行更新和升级。扩展功能:程序员可以通过创建DLL来扩展应用程序的功能而无需重编译整个程序。 阅读详情

相关推荐

delphi延时函数(相当于sleep函数)

delphi延时函数(相当于sleep函数),比sleep函数好,不会使界面停顿,像死机那样

Delphi中三种延时方法

Delphi中三种延时方法

qq_33577118的博客 3791

高精度定时器最高精度 1ms

delphi 下的高精度定时器组件,支持分辨率最小 1ms。可用于精确定时和计数。带测试例子。

Delphi中实现程序的延时的方法

在Delphi中,通常可以用以下三种方法来实现程序的延时,即TTtimer控件,Sleep函数,GetTickCount函数。但是其精度是各不相同的。 一、三种方法的简单介绍1)TTtimer控件  TTtimer控件的实质是调用Windows API定时函数SetTimer和KillTimer来实现的,并简化了对WM_TIMER 消息的处理过程。通过设置OnTimer事件和Inter

pmj888666的专栏 3750

delphi取微秒级时间间隔

delphi取微秒级时间间隔

深入解析AndroidManifest.xml与device_admin.xml:打造完美DeviceOwner应用配置

本文深入解析了Android企业级开发中DeviceOwner应用的核心配置文件AndroidManifest.xml与device_admin.xml。详细阐述了如何精准声明DeviceAdminReceiver、定义管理策略,并提供了通过ADB命令进行设置与验证的实战指南,帮助开发者构建权限完整、配置正确的设备所有者应用。

ice55的博客 679

延时方法及其定时精度分析

Delphi中,通常可以用以下三种方法来实现程序的延时,即TTtimer控件,Sleep函数,GetTickCount函数。但是其精度是各不相同的。    一、三种方法的简单介绍    1)TTtimer控件    TTtimer控件的实质是调用Windows API定时函数SetTimer和KillTimer来实现的,并简化了对WM_TIMER 消息的处理过程。通过设置OnTimer事件和Int

熊出没危险 2129

Vivado加上VsCode让你的生活更美好

VsCode与Vivado的灵活使用 引言 ​ 现在大二了,在接触硬件描述语言。Vivado自带的编辑器实在很难用,为了能够“极客”一些,当然是去Google了一下有哪些方法可以取而代之。 ​ 网络上的答案大同小异,基本上都是用的Sublime Text.(我的学长们也几乎都是) 平时码代码的过程中,我习惯与使用VsCode,尤其是在微软收购GitHub之后,Code 简直就是神器了。于是乎…一个...

qq_39498701的博客 10万+

Delphi延时

// 高精度的延时,精确到Ms , 100ms以内采用,或要求误差极小 // 删除Application.ProcessMessages 影响精度 procedure DelayMsEx(Ms: LongWord); var iFreq, iStartCounter, iEndCounter: Int64; begin QueryPerformanceFrequency(iFreq);

喜欢折腾的开发,Android Java Python 就是玩儿。 1908

通信系统原理[郭宇春]——模拟调制系统——课后习题答案

通信系统原理[郭宇春]——第三章课后习题答案,出错望指正!

尧呱呱的博客 3843

GEE:关于遥感生态指数(RSEI)的若干疑问

本文记录了若干关于在 Google Earth Engine (GEE)平台上,计算基于主成分分析(PCA)的遥感生态指数(RSEI)的问题。并记录了解决这些问题的一些答案。问题包括,主成分分析的特征值的正负,主成分的占比,去云后空值像素的处理方法,异常值处理方法,如何看载荷等。

养乐多的博客 3416

Delphi 实现微妙级别的延迟函数

今天群内 和 一群友 争论 GetTickCount 和QueryPerformance 的时间误差 以及精度问题,以及windows 上实现毫秒级别的定时(硬件通信需要)。故开始研究 这个问题。 Delphi 下没有 网上搜了一下 有不少C++ 版本的实现 ,翻译到delphi 吧 //微妙级别的延迟函数 测试误差在2us 左右 测试机器 i3 3.2ghz //一路随云 proc

等灯等灯等灯! 3751

软件需求规格说明书(SRS)标准模板

《软件需求规格说明书(SRS)框架解析》摘要: 本文档系统阐述了SRS的标准结构,包含7大核心部分:1)引言(目的、背景和术语);2)总体描述(产品定位与用户特征);3)功能需求(模块化功能说明);4)非功能需求(性能、安全等指标);5)接口需求(用户/硬件/软件接口);6)其他技术要求;7)附录(图表与参考资料)。重点突出了功能需求模块的标准化描述模板(FR-01),以及安全需求中的HTTPS通信、SHA-256加密等关键指标。该框架为软件开发提供了明确的需求基准,涵盖从业务背景到技术实现的完整链条,是确

moton2017的博客 2881

Windows c语言精确定时,VC中基于Windows的精确延时(最全面的介绍).doc

int zhouxuanze=((CComboBox*)GetDlgItem(IDC_COMBO1))->GetCurSel();switch(zhouxuanze){case 0:{axis=0;Axis9="X";}break;case 1:{axis=1;Axis9="Y";}break;case 2:{axis=2;Axis9="Z";}break;default:break;}++...

weixin_33583401的博客 796

华为OD机试新系统真题【仓库盘点】

华为OD机试真题 新系统【仓库盘点】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【仓库盘点】

qq_45776114的博客 567

AUTOSAE软件配置-项目标准配置 (PSC) 导入达芬奇( DaVinci Configurator)

文件是“可拆分的”,这意味着如果格式符合 AUTOSAR 拆分规则,则可以与其他。)是一个ARXML文件,主要由OEM提供,其中包含。)工件,可以作为输入文件导入到达芬奇配置器专业版。导入的参数将以只读方式处理。不允许在多个 ARXML 文件中导入一个。的已存在数据或从输入文件派生的数据。可以作为输入文件导入到另一个。文件会覆盖用户配置的基本。元素和诊断数据预配置。定义 [数据结构]。中,可以导出一个或多个。

m0_49148264的博客 1004

延迟函数

在Delphi中,通常可以用以下三种方法来实现程序的延时,即TTtimer控件,Sleep函数,GetTickCount函数。但是其精度是各不相同的。一、三种方法的简单介绍1)TTtimer控件  TTtimer控件的实质是调用Windows API定时函数SetTimer和KillTimer来实现的,并简化了对WM_TIMER 消   息的处理过程。通过设置OnTimer事件和Inter

夜行血手的专栏 1222

禾赛激光雷达AT128P/海康相机(1):ROS环境设备驱动

sudo cp *.so /opt/MVS/lib/64/ # 复制当前文件夹中所有.so文件 到 “/opt/MVS/lib/64/” 文件中。将相应的.so文件复制到 /opt/MVS/lib/64/。我解压的是x86_64的,解压之后,打开,再解压MVS。然后在上一层,也就是选择x86_64那一层打开终端。新建一个工作空间,或者打开自己的工作空间。)包放在src内,并解压,然后编译。MVS V2.1.2下载之后解压,// 驱动代码下载到src文件里面。// 特定文件夹中打开终端。

努力努力努力 882

多媒体定时器

虽然Win95下可视化开发工具如VC、Delphi、C++ Builder等都有专用的定时器控件Timer,而且使用很方便,可以实现一定的定时功能,但最小计时精度仅为55ms,且定时器消息在多任务操作系统中的优先级很低,不能得到及时响应,往往不能满足实时控制环境下的应用。不过Microsoft公司在Win32 API函数库中已经为用户提供了一组用于高精度计时的底层函数,假如用户使用得当,计时精度可到1ms。这个计时精度、对于一般的实时系统控制完全可以满足要求。现将由C++ Bui

Lewen的编程博客 898

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Delphi常用批处理命令

# getconf LONG_BIT 32 (说明当前CPU运行在32bit模式下, 但不代表CPU不支持64bit) # cat /proc/cpuinfo | grep flags | grep ' lm ' | wc -l 8 (结果大于0, 说明支持64bit计算. lm指long mode, 支持lm则是64bit) 二、批处理命令获取当前盘符和当前目录 当前盘符:%~d0 当前路径...

xtfnpgy 1298

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

[C++ VC MFC] Windows 的定时机制

方式一:VC中的WM_TIMER消息映射能进行简单的时间控制。首先调用函数SetTimer()设置定时间隔,如SetTimer(0,200,NULL)即为设置200ms的时间间隔。然后在应用程序中增加定时响应函数 OnTimer(),并在该函数中添加响应的处理语句,用来完成到达定时时间的操作。这种定时方法简单,但精度非常低,最小计时精度仅为30ms,CPU占用低,且定时器消息在多任务操作系统中的优

毛C毛Py的专栏 1048

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

上一篇: 钩子(HOOK)机制的使用
下一篇: Delphi托盘编程实战演练
thinkray
博客等级 码龄22年 0粉丝 1原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值