Delay函数疑问
vb吧
全部回复
仅看楼主
level 7
随心网络 楼主
多个窗体下有多个timer执行不同工作
Timer中调用Delay函数
函数放在通用模块下会导致延迟不准(变量值错乱)
函数放在类模块下也会导致各种问题
Form1
Dim i
Private Sub Form_Load()
Timer1.Enabled = True
Timer1.Interval = 1000
Timer2.Enabled = True
Timer2.Interval = 1234
End Sub
Private Sub Timer1_Timer()
i = i + 1
Me.Caption = i
Dim t1 As New Class1
t1.Delay 1000
End Sub
Private Sub Timer2_Timer()
i = i + 1
Me.Caption = i
Dim t2 As New Class1
t2.Delay 5000
End Sub
Module1
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public Declare Function timeGetTime Lib "winmm.dll" () As Long
Class1
Public Sub Delay(nTime As Long)
Dim time1, time2
Debug.Print "开始延迟:" & nTime
time1 = timeGetTime
Do
Sleep 2
DoEvents
time2 = timeGetTime - time1
If time2 < 0 Then time2 = time2 + (2 ^ 32)
Loop While time2 < nTime
Debug.Print "实际延迟:" & time2
End Sub
实际测试结果两个Timer会一起结束
开始延迟:1000
开始延迟:5000
实际延迟:5000
实际延迟:5234
开始延迟:1000
开始延迟:5000
实际延迟:5001
实际延迟:5238
开始延迟:1000
开始延迟:5000
实际延迟:5000
实际延迟:5217
开始延迟:1000
开始延迟:5000
实际延迟:5000
实际延迟:5235
开始延迟:1000
开始延迟:5000
实际延迟:5001
实际延迟:5237
开始延迟:1000
开始延迟:5000
实际延迟:5001
实际延迟:5224
开始延迟:1000
开始延迟:5000
实际延迟:5000
实际延迟:5238
开始延迟:1000
开始延迟:5000
实际延迟:5000
实际延迟:5219
开始延迟:1000
开始延迟:5000
实际延迟:5000
实际延迟:5223
2018年08月26日 00点08分 1
level 7
随心网络 楼主
请问有没有更好的办法确保每个过程下都单独延迟,不冲突
我尝试在通用模块下复制两个过程Delay1和Delay2 也都是很奇怪的表现
现在有点怀疑DoEvents有问题
2018年08月26日 00点08分 2
level 15
你到底想用控件还是循环实现延时……这两者只需要用一个吧
2018年08月26日 01点08分 3
感觉你没理解我的意思……用Timer控件也是延时,用循环也是延时,但是我猜两者混用就会导致你的这个问题,所以我想让你试试只用其中一种方法
2018年08月26日 03点08分
@初音✨七奈 前辈帮我看下楼下,我实际是需要延迟能在不同事件同时执行不冲突,Timer控件应该跟这个无关了
2018年08月29日 00点08分
level 7
随心网络 楼主
想要在不同的事件中可以同时实现的互不影响的延迟
2018年08月26日 02点08分 4
吧务
level 14
多线程?
2018年08月26日 02点08分 5
level 7
随心网络 楼主
没用多线程,用多个Timer控件来监控不同的状态,是需要延迟类,只要能实现多个延迟不冲突就行
2018年08月26日 02点08分 6
level 7
随心网络 楼主
或者复制多个延迟过程在通用模块下,我把变量都改成不同的了,还是不行,这就有点奇怪了..
2018年08月26日 02点08分 7
level 7
随心网络 楼主
@miku_con
我尝试把Class1中的Delay过程复制一份副本,重命名为Delay1和Delay2
两个Command如下
Private Sub Command1_Click()
Dim t1 As New Class1
t1.Delay 1000
t1.Delay 1000
t1.Delay 1000
t1.Delay 1000
t1.Delay 1000
t1.Delay 1000
t1.Delay 1000
Set t1 = Nothing
End Sub
Private Sub Command2_Click()
Dim t2 As New Class1
t2.Delay2 5000
t2.Delay2 5000
t2.Delay2 5000
Set t1 = Nothing
End Sub
按钮1是1秒x7次
按钮2是5秒x3次
'-----------------------------------调试输出
Debug.Print "2实际延迟:" & time2 & " " & timeGetTime
1开始延迟:1000 838953041
2开始延迟:5000 838953740
2实际延迟:5000 838958740
2开始延迟:5000 838958743
2实际延迟:5001 838963744
2开始延迟:5000 838963746
2实际延迟:5001 838968747
1实际延迟:15707 838968748
1开始延迟:1000 838968749
1实际延迟:1000 838969749
1开始延迟:1000 838969750
1实际延迟:1000 838970750
1开始延迟:1000 838970751
1实际延迟:1000 838971751
1开始延迟:1000 838971751
1实际延迟:1000 838972751
1开始延迟:1000 838972753
1实际延迟:1000 838973753
1开始延迟:1000 838973755
1实际延迟:1000 838974755
我是按下按钮1大概700ms后按的按钮2
这情况看起来很明显,按钮2后执行,但执行3次全部完毕后才继续按钮1的事件
按钮1的第一次延迟,实际经过了5000x3+700ms(两次按钮按下的间隔)
2018年08月29日 00点08分 8
嗯,这个测试似乎说明了DoEvents的执行原理,其实按照MSDN的说法,这叫“转让控制权”,也就是触发了其他事件之后,DoEvents处的代码执行就会被暂停,转而执行其他代码。所以用DoEvents是不能实现互不冲突的延时的
2018年08月29日 02点08分
@初音✨七奈 那我多个延迟同时执行的需求还有什么好的解决办法吗?因为脚本代码写得比较多,所以流程上是个固定模式,也是个成熟的模式,我也想过用一个timer控件来解决,不过整体结构变化比较大
2018年08月29日 03点08分
吧务
level 13
时钟计数器
  在 VB 中,时钟计数器一般是由时钟控件【Timer】来实现。
  如果要分时间段做各种事情,就应该引入【工业控制中的时钟】理念。
  无论有多少种控制,时钟计时器只需要一个,这个时钟计时器的精度与控制精度有关。
  例如每秒钟发10个脉冲,就是 0.1 秒的精度。
  自动控制程序只需要三个大的功能:
  一是时钟计数器:当时钟(前沿——上跳沿)到来时,计数变量的值自动加一;
  二是自动控制器:当时钟计数变量的值到达某个数字时, 就去做某个具体的事情。对于 VB 来说,就是去调用某个子程序;
  三是清零功能:当计数变量的值到达某个数字时,将计数变量的值清零,重新开始。
  如果要调用的子程序比较多的时候,就需要做一个求【最小公倍数】的工作,来确定计数变量的【清零】位置。
2018年08月29日 02点08分 11
多个延迟同时执行的需求还有什么好的解决办法吗?因为脚本代码写得比较多,所以流程上是个固定模式,也是个成熟的模式,我也想过用一个timer控件来解决,不过整体结构变化比较大,如果实在没办法,只有使用timer来控制,不过工作量比较大,实现应该是可以实现的
2018年08月29日 03点08分
1