Timer 计时器事件是否可以重新进入?

Timer 计时器事件是否可以重新进入?,timer,vb6,message-queue,Timer,Vb6,Message Queue,我正在检查一些可怕的遗留代码,其中包含一个计时器事件和一些包含DoEvents调用的冗长代码。简化版本如下所示: Private Sub tmrProcess_Timer() 'Run some slow processing code here DoEvents 'More slow code here DoEvents 'Lots more slow code and the occasional DoEvents here

我正在检查一些可怕的遗留代码,其中包含一个计时器事件和一些包含DoEvents调用的冗长代码。简化版本如下所示:

   Private Sub tmrProcess_Timer()
      'Run some slow processing code here
      DoEvents
      'More slow code here
      DoEvents
      'Lots more slow code and the occasional DoEvents here
      If booComplete Then
         tmrProcess.Enabled = False
      End If
   End Sub
计时器的时间间隔设置为250,慢代码可能需要30秒左右才能完成。请注意,表单上有一个按钮,单击该按钮时会将booComplete设置为True

如果VB6是单线程的,并且计时器消息的优先级较低,那么在DoEvents调用期间是否有可能重新输入计时器事件,或者如果计时器事件当前正在执行,VB6运行时是否会阻止计时器事件的执行


他有一些相关的信息。特别指出,WM_PAINT消息被合并到一条消息中,但没有提及是否合并WM_TIMER消息。

为避免重新进入,请禁用计时器,直到执行计时逻辑,然后再次启用

Private Sub tmrProcess_Timer()
  tmrProcess.Enabled = False

  'your time taking logic goes here ......

  tmrProcess.Enabled = True
End Sub

首先,大多数包含DoEvents的代码都不需要它,这是一个神奇的词,人们会觉得不得不使用它(但不知道为什么)

DoEvents允许重入任何内容,而不仅仅是计时器

您的是TimerProc。如果您选择了一条消息,那么只有当消息队列为空并且您询问“他们有消息吗?”,wm_定时器消息才会出现。如果它们是绘画、计时器或鼠标移动类型的消息挂起,则如果队列为空,则它们才可用


尽管存在明显的联系,但这是其来源:

> mk:@MSITStore:C:\Program%20Files\Microsoft%20Visual%20Studio\MSDN\2001OCT\1033\kbvb.chm::/Source/vbapps/q118468.htm
(当然,您必须安装与我相同的库才能工作。)

为什么你认为来源是互联网

Visual Basic for Applications中DoEvents的定义

Q118468


本条中的信息适用于:

Microsoft Visual Basic for Applications 1.0版Microsoft Excel 对于Windows,版本5.0、5.0c Microsoft Excel for the Macintosh, 版本5.0、5.0a Microsoft Excel for Windows 95、版本7.0、7.0a Microsoft Excel 97 for Windows Microsoft Excel 98 Macintosh Edition


DoEvents函数放弃宏so的执行 操作系统可以处理其他事件。DoEvents 函数将控制从应用程序传递到操作系统。 DoEvents可能有用的一些实例包括:

硬件I/O

延迟环

操作系统调用

死锁

本文还讨论了与 DoEvents功能

更多信息

硬件I/O如果代码等待来自任何I/O设备的输入,则 DoEvents函数通过多任务处理加速应用程序。作为一个 结果,计算机似乎没有暂停或停止响应(挂起) 当代码正在执行时

例如:

打开“com1”输入为#1输入#1,x Do,直到x=Chr(13)DoEvents '... '... 输入#1,x循环延迟循环在延迟循环中,DoEvents 函数可以允许CPU操作系统继续执行任何操作 未决工作

例如:

X=计时器()执行,而X+10>计时器()执行

当Visual Basic调用 操作系统,操作系统甚至可以返回控制 在完全处理命令之前。这样做可能会防止出现任何问题 宏代码,该代码依赖于由调用生成的对象 跑步在下面的示例中,Shell函数启动Microsoft 文字应用。如果这个词还没有公开,任何建立 DDE链接到它将停止代码。通过使用DoEvents,您的过程 确保操作(如Shell)已完全执行 在处理下一个宏语句之前

例如:

z%=Shell(“WinWord Source.Doc”,1)DoEvents。。。死锁 考虑一种情况,其中VisualBasic宏调用 正在等待第二个应用程序获取某些数据的应用程序。 如果宏不控制第二个应用程序,则 结果是一个僵局。在多个用户之间的DDE对话中 应用程序中,使用DoEvents可以消除这种类型的 死锁。与DoEvents关联的问题使用太多嵌套 DoEvents语句可能会耗尽堆栈空间,从而生成 “堆栈空间不足”错误消息。此错误是指 分配给Microsoft Excel应用程序的应用程序堆栈空间

确保已放弃DoEvents控制的程序未被执行 在第一次执行之前,从代码的不同部分再次执行 电话回传;这可能导致不可预测的结果

一旦DoEvents将控制权交给操作系统,它就不会 可以确定Microsoft Excel何时恢复控件。 在操作系统获得处理器控制权后,它将 处理当前在消息队列中的所有挂起事件 (例如鼠标单击和按键)。这可能不适合某些人 实时数据采集应用

参考有关DoEvents的详细信息,请单击搜索 “帮助”中的按钮并键入:

多芬特

附加查询词:Sendkeys击键等待XL98 XL97 XL7 XL5

关键词:问题类型:技术:kbHWMAC kbOSMAC kbExcelSearch KBZNOT关键字6 kbExcel95 kbExcel500 kbExcel98 kbExcel95搜索 KBExcel97搜索KBExcel98搜索kbExcelMacsearch kbVBASearch KBZNOT关键字3 kbExcel500Mac kbExcel500aMac kbExcel500c kbExcel95a kbVBA100

最后审查日期:2001年1月17日©2001微软公司。全部的 版权所有。使用条款


向MSDN发送反馈。请在此处查找MSDN联机资源


我原以为它会再进来,但似乎不会

请查看以下测试项目:

'1 form with:
'  1 timer control : Name=Timer1

Option Explicit

Private Sub Form_Load()
  WindowState = vbMaximized
  Timer1.Interval = 2000
End Sub

Private Sub Timer1_Timer()
  Static intCount As Integer
  Dim sngTime As Single
  intCount = intCount + 1
  Print CStr(Now) & " Timer event fired " & CStr(intCount)
  sngTime = Timer + 3
  Do While sngTime > Timer
    DoEvents
  Loop
  Print CStr(Now) & " End of timer event " & CStr(intCount)
End Sub
  • 加载表单2秒后,您将看到“开始”
  • 3秒后你会看到一个“结束”
  • 在显示上一个“结束”2秒后,您将看到一个“开始”
  • 您将看到“结束”3秒