【问题标题】:VB6 Timer IssueVB6 定时器问题
【发布时间】:2012-06-14 16:46:28
【问题描述】:

我有一个有计时器问题的旧 VB6 应用程序。有一个模态表单,其中包含一些元素和两个计时器(VB6 标准计时器)。每个定时器都是这样工作的(伪代码):

-- TimerEvent Start 
DoSomething
DoEvents
-- TimerEvent End

然后,在某个时间点,会引发来自 OCX 控件的某个连接丢失的事件。与计时器本身无关。但是此时,两个计时器都不再引发计时器事件,尽管 - 现在很奇怪 - 计时器已启用并设置了 2000 的间隔。即使重新启用和重新设置间隔也没有任何效果。当来自同一 OCX 控件的另一个事件引发连接已恢复时,计时器事件会突然再次引发。 即使删除 OCX 控件事件处理程序中的所有代码,计时器也不起作用。

我对 DoEvents “模式”不是很熟悉,但我认为问题一定与 DoEvents 有关。删除它并没有改变任何东西。

有人知道这里会发生什么吗?我已经在寻找任何可以阻止计时器引发已逝事件的全局设置,但看在上帝的份上,我找不到任何设置。

我要疯了……

感谢您的帮助。

【问题讨论】:

  • 我非常怀疑问题出在您引用的代码中。相反,我怀疑 OCX 控件是用 C/C++ 编写的,并且直接与应用程序的消息泵混淆,从而破坏了你的计时器。
  • 已经有一段时间了,但是 DoEvents 基本上是在您长时间阻塞主线程时清空事件队列。我不确定它的确切效果 - 我知道在某些情况下,连续多次调用 DoEvents 是必要的。它的主要用途是在执行更长时间的处理时继续绘制 UI 并响应用户输入。我不确定您为什么要在事件处理程序的 END 调用它,但我认为它实际上不会在那里产生任何影响。
  • 您的问题可能归结为 OCX 在某处调用 GetMessage() 并消耗了您的计时器事件。我怀疑,但不确定,VB6 定时器只是在下面使用 WM_TIMER。也许OCX,听起来像是一个网络库,内部使用了一个WM_TIMER作为它的超时,并且错误地将VB6定时器的消息解释为它自己的超时消息。
  • 我已经有一段时间没有接触 VB6 了,但通常你不会把自己弄得一团糟——它几乎总是一个外部 C 库。祝你好运!
  • 计时器确实在幕后使用了 WM_TIMER,我想这些消息可能会被消耗掉。调用 DoEvents 获取并分派当前线程的 windows 消息队列中的任何消息,直到它为空。应该避免它,因为它会导致重入问题。

标签: vb6 timer


【解决方案1】:

抱歉回复晚了。

这是另一个计时器内部的计时问题。这个另一个计时器 ping 另一个 IP,ping 超时为 200 毫秒。此计时器间隔为 200 毫秒。因此,如果 ping 超时(因为另一台机器已断开连接),则计时器的触发频率超过了可以处理的频率。所以它弄乱了事件队列并阻止了所有其他计时器的触发。 通过将计时器间隔增加到 1000 毫秒,它可以工作,尽管更好的解决方案是停止计时器,处理事件,然后重新启动计时器。

感谢您的有用提示!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-18
    • 2023-03-31
    • 2012-01-11
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    相关资源
    最近更新 更多