Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public Function Delay(DT As Long)For i = 0 To DT Step 2
DoEvents '操作权交给系统 否则程序会暂时无响应
Sleep 1
Next iEnd Function==============
写以上程序的作者在主程序中还有这么一段注释。
Delay 2000
End '延时两秒后程序自动结束
================
我的第一个疑问是 Step 2 的情况下Delay 2000难道不是只延迟一秒吗?
奇怪的是,当我运行时作者却是对的。
这难道还跟平台有关,我用的是个VB 6迷你版的。第二个问题就很奇葩了:我前两天用Delay 60000   来延迟一分钟,生成了.exe正常运行。  然后今天还用这个exe时变成了延迟9分钟10分钟的样子。我自己的机器没有人修改过这个exe

解决方案 »

  1.   

    我没看出:作者“对”在哪里。
    并且我实际测试结果也明显不支持楼主的说法。
    按我的测试,Delay 2000的结果是15秒多时间,
    如果 Delay 60000的话,算下来超过936秒,也就是超过15分钟半以上(没有实际运行,按测试结果计算的),
    并不是楼主所说的9、10分钟的样子。
    别跟我说是“机子”或“系统”问题,我在两台主机上运行过 .exe ,结果没什么差别:
    一台是 WinXP,DELL主机,3.2G双核(E5800);
    另一台是Win7专业版32位,联想主机,3.0G双核(G3220)。我在IDE下运行,和编译成 .exe运行,结果一样(WinXP这台)。
    以前论坛中就有一个帖子讨论过这些“时间精度”的问题,Sleep的“精度”根本就达不到1ms的级别,只有10多ms。
    建议楼主查找一下。我的测试代码如下:
    Option ExplicitPrivate Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    Private Function Delay(DT As Long)
       Dim i As Long
       For i = 0 To DT Step 2
          DoEvents '操作权交给系统 否则程序会暂时无响应
          Sleep 1
       Next
    End Function
    Private Sub Command1_Click()
       Dim t1!, t2!
       Dim lDT As Long   Me.Cls
       Print "2秒测试:"
       lDT = 2000     ' 延时2秒?
       t1 = Timer()      ' 开始时间
       Call Delay(lDT)
       t2 = Timer()      ' 延时结束时间
       Print t1
       Print t2
       Print "实际延时:" & Format$(t2 - t1, "0.00秒")
       Print "平均周期:" & Format$((t2 - t1) / (lDT / 2 + 1), "0.0000")
       Me.Print vbCrLf & "1秒测试:"
       lDT = 1000     ' 延时1秒?
       t1 = Timer()      ' 开始时间
       Call Delay(lDT)
       t2 = Timer()      ' 延时结束时间
       Print t1
       Print t2
       Print "实际延时:" & Format$(t2 - t1, "0.00秒")
       Print "平均周期:" & Format$((t2 - t1) / (lDT / 2 + 1), "0.0000")
       Me.Print vbCrLf & "0.1秒测试:"
       lDT = 100      ' 延时0.1秒?
       t1 = Timer()      ' 开始时间
       Call Delay(lDT)
       t2 = Timer()      ' 延时结束时间
       Print t1
       Print t2
       Print "实际延时:" & Format$(t2 - t1, "0.00秒")
       Print "平均周期:" & Format$((t2 - t1) / (lDT / 2 + 1), "0.0000")
    End Sub
      

  2.   

    本想插入一张运行结果的图片,但总是不成功。
    (不知道是IE问题,还是公司的网络访问限制造成的)用文字大致说一下:
    Delay 2000,理论上应该是2秒,测试结果是15.64
    Delay 1000,理论上应该是1秒,测试结果是7.83
    Delay 100,理论上是0.1秒,测试结果是0.80秒
    注意我是简单的用Timer函数获取系统时间,这个的“理论精度”才0.01秒,精度比较低的。
    因此上面的结果“倍数比例”有明显差异,也是正常的。代码中计算的“平均周期”就是 Delay( ) 函数中每次 For循环的执行周期,
    这个时间主要在 Sleep 1 那儿,理论上应该是1ms(或者说按作者 Step 2 ,应该是2ms),
    但我的测试结果,基本上是15.63ms 。
    可见这个差距是非常之大的!!!
      

  3.   

    换句话说,如果要“比较精确”的进行延时,用 Sleep来计次循环,根本就是“不靠谱”!!!如果要延时做得比较准确,必须是进入“延时”时获取当前时间(起点)、然后Do循环/ Sleep / DoEvents
     在Do循环中再不停的获取“当前时间”,计算与起点的时间差,当大于等于延时,就跳出Do循环,延时结束返回。
    这样才可以比较准确的延时,“延时精度”取决于获取“时间”的精度,
    具体用什么方式,就看实际需求了。
      

  4.   

    谢谢,sleep的“精度”我知道不靠谱了,但那个Delay函数还是不太懂。Public Function Delay(DT As Long)
     
    For i = 0 To DT Step 2
     DoEvents '操作权交给系统 否则程序会暂时无响应
     Sleep 1
     Next i
     
    End Function
     
    假设sleep是标准的1ms,在step为2的情况下,Delay 2000,理论上是1秒吧。
      

  5.   


    很明显,你代码中循环调用的DoEvents 这一句,他所需要的时间是不确定的啊,而你竟然还说,"Delay 2000,理论上是1秒吧",荒唐:)
      

  6.   

    Private Function Delay(DT As Long)
       Dim i As Long
       For i = 0 To DT Step 2
          DoEvents '操作权交给系统 否则程序会暂时无响应
          Sleep 1
       Next
    End Function这类的延时方法是非常不准确的!会受机器硬件、运行环境、运行的线程等因素影响
    Private Function Delay(DT As Long)
       Dim t0 As Long
     
       t0=GetTickcount()
       do while 1
          if gettickcount-t0>dt then exit do
          DoEvents '操作权交给系统 否则程序会暂时无响应
          Sleep 1
       loop 
    End Function
      

  7.   

    Windows延时精度≈15ms