Timer控件是不可重入?对象不可重入?类不可重入?
Timer控件.
同时存在两个timer控件,并且处理时间的超过interval的时候,就出现一些比较恶心的情况.
2个timer一个设置20,一个30,正常理解是2个timer处理完循环后,把自己的时间信息显示到自己对应的label,
但是实际情况变化了,只有一个label在更新,另外一个没有更新.
如果你的机器比较快,需要把循环时间调整更长一些,就是设置文本框里面的数字更大些.
我的问题是:是否timer是不可重入的?是否整个工程(或者是活动的这个窗体)里的多个timer也是限制重入,就是一个timer处理过程中
的时候,其他timer是阻塞的?
我的例子如下:
VERSION 5.00Begin VB.Form Form1 Caption = "Form1" ClientHeight = 2430 ClientLeft = 60 ClientTop = 345 ClientWidth = 4680 LinkTopic = "Form1" ScaleHeight = 2430 ScaleWidth = 4680 StartUpPosition = 3 '窗口缺省 Begin VB.CommandButton Command2 Caption = "Start" Enabled = 0 'False Height = 495 Left = 2880 TabIndex = 4 Top = 720 Width = 1575 End Begin VB.CommandButton Command1 Caption = "Stop" Height = 495 Left = 2880 TabIndex = 3 Top = 1320 Width = 1575 End Begin VB.TextBox Text1 Height = 270 Left = 2040 TabIndex = 0 Text = "500" Top = 240 Width = 975 End Begin VB.Timer Timer2 Interval = 30 Left = 0 Top = 960 End Begin VB.Timer Timer1 Interval = 20 Left = 0 Top = 1440 End Begin VB.Label Label3 AutoSize = -1 'True Caption = "设置一个值,500-60000" Height = 180 Left = 0 TabIndex = 5 Top = 240 Width = 1800 End Begin VB.Label Label2 AutoSize = -1 'True Caption = "Label2" Height = 180 Left = 480 TabIndex = 2 Top = 960 Width = 540 End Begin VB.Label Label1 AutoSize = -1 'True Caption = "Label1" Height = 180 Left = 480 TabIndex = 1 Top = 1440 Width = 540 EndEndAttribute VB_Name = "Form1"Attribute VB_GlobalNameSpace = FalseAttribute VB_Creatable = FalseAttribute VB_PredeclaredId = TrueAttribute VB_Exposed = FalseOption ExplicitDim bStop As BooleanDim lCount As LongPrivate Sub Command1_Click()bStop = TrueTimer1.Enabled = FalseTimer2.Enabled = FalseCommand1.Enabled = FalseCommand2.Enabled = TrueEnd SubPrivate Sub Command2_Click()bStop = FalseTimer1.Enabled = TrueTimer2.Enabled = TrueCommand1.Enabled = TrueCommand2.Enabled = FalseEnd SubPrivate Sub Form_Load()lCount = Val(Text1.Text)End SubPrivate Sub Text1_Change()If Not bStop Then MsgBox "先停止那两个计时器"Else lCount = Val(Text1.Text)End IfEnd SubPrivate Sub Timer1_Timer()Dim i, j, k, lk = TimerFor i = 1 To lCount For j = 1 To lCount l = j If bStop Then Exit Sub DoEvents Next jNext iLabel1.Caption = Timer & " " & Timer - kEnd SubPrivate Sub Timer2_Timer()Dim i, j, k, lk = TimerFor i = 1 To lCount For j = 1 To lCount l = j If bStop Then Exit Sub DoEvents Next jNext iLabel2.Caption = Timer & " " & Timer - kEnd Sub
SetTimer肯定是单线程的,建议试试参考这个代码改成timeSetEvent的试试。实在不行的话就要考虑用多线程来弄。
'This project requires a Form and a Module'On the form, there should be one command button (Command1)'and one Timer (Timer1)'In the form:Option ExplicitPrivate Sub Form_Load() 'KPD-Team 2001 'URL: http://www.allapi.net/ 'E-Mail: KPDTeam@Allapi.net Command1.Caption = "Start"End SubPrivate Sub Form_Unload(Cancel As Integer) 'Stop the timers if they're still counting timeKillEvent hMMTimer Timer1.Enabled = FalseEnd SubPrivate Sub Timer1_Timer() 'increment VBTimer VBTimer = VBTimer + 1End SubPrivate Sub Command1_Click() If Command1.Caption = "Start" Then 'Start both timers Timer1.Interval = 1 Timer1.Enabled = True hMMTimer = timeSetEvent(1, 0, AddressOf TimerProc, 0, TIME_PERIODIC Or TIME_CALLBACK_FUNCTION) Command1.Caption = "Stop" Else 'Stop both timers timeKillEvent hMMTimer Timer1.Enabled = False Command1.Caption = "Start" 'Show result MsgBox "Timer1_Timer was called " & VBTimer & " times;" & vbNewLine & "TimerProc was called " & MMTimer & " times." VBTimer = 0 MMTimer = 0 End IfEnd Sub'In a moduleOption ExplicitPublic Const TIME_ONESHOT = 0 'Event occurs once, after uDelay milliseconds.Public Const TIME_PERIODIC = 1 'Event occurs every uDelay milliseconds.Public Const TIME_CALLBACK_EVENT_PULSE = &H20 'When the timer expires, Windows calls thePulseEvent function to pulse the event pointed to by the lpTimeProc parameter. The dwUser parameter is ignored.Public Const TIME_CALLBACK_EVENT_SET = &H10 'When the timer expires, Windows calls theSetEvent function to set the event pointed to by the lpTimeProc parameter. The dwUser parameter is ignored.Public Const TIME_CALLBACK_FUNCTION = &H0 'When the timer expires, Windows calls the function pointed to by the lpTimeProc parameter. This is the default.Public Declare Function timeKillEvent Lib "winmm.dll" (ByVal uID As Long) As LongPublic Declare Function timeSetEvent Lib "winmm.dll" (ByVal uDelay As Long, ByVal uResolution As Long, ByVal lpFunction As Long, ByVal dwUser As Long, ByVal uFlags As Long) As LongPublic VBTimer As Long, MMTimer As LongPublic hMMTimer As LongSub TimerProc(ByVal uID As Long, ByVal uMsg As Long, ByVal dwUser As Long, ByVal dw1 As Long, ByVal dw2 As Long) 'Increment MMTimer MMTimer = MMTimer + 1End Sub
[解决办法]
VB中的定时器为单线程运行,当时间到,但是程序还在处理别的事情,定时消息会被吞没
LZ的定时时间值太短,单个定时器经常最小的定时时间也就是12-20ms,再小也没有用
[解决办法]
VB的Timer控件精度有限,试一试这个
http://download.csdn.net/detail/veron_04/3517180
[解决办法]
把两个 DoEvents 语句去掉就可以了。
DoEvents 使用不当!
[解决办法]
你的问题主要是 DoEvents 而不是 Timer!!!
[解决办法]