【问题标题】:TTimer Stops by itselfTTimer 自行停止
【发布时间】:2011-03-09 22:07:32
【问题描述】:

我在我的软件中使用 TTimer,它应该 24/7 全天候运行。在我的软件中,计时器没有被禁用或停止运行。它的主要功能是更新表的值。它在软件运行后立即启动,从那时起 TTimer 不应停止。然而,在运行了一个多月后,那个 TTimer 神秘地停止了运行。该软件在Windows 7上运行,软件在Delphi 2010 XE上开发。我已经搜索了我的代码以查看可能导致它的原因,但我无法弄清楚是什么原因。

 Timer1.Enabled:=true;

这就是计时器的启动方式。

更新: 经过一番调查,我发现 TTimer 从未停止过,但还有另一个问题。我在 TForm 上的 TStringGrid 表根本不显示任何正在更新的值。此外,我还发现我用来存储数据项列表的 TList 列表正在以某种方式被破坏,导致列表变为空。但是列表中的数据项只有在程序启动时才被加载,并不会在代码中的任何地方被删除。

每次我更新表单上的 TStringGrid 时,我都会遍历我的 TList 项目从 0 到 count-1 位置。因此,如果内存中的 TList 中没有项目,我的代码就会跳过 在显示部分上,因此 TStringGrid 上没有任何更新。

类似:

If (List.count>0) then 
begin
//Display values in TStringGrid; 
end;

但是当软件仍在运行时,我能够从文件中重新加载我的项目列表 回到 TList 列表,我的软件开始按预期工作。

我不想说程序员最讨厌的最丑陋的词。恐怕我可能有内存泄漏。有人这么认为吗?

任何帮助将不胜感激。谢谢。

【问题讨论】:

  • 如何知道 OnTimer 事件是否不再触发?我建议您在 OnTimer 事件的第一行记录一个条目,运行它所需的时间,直到它停止工作并检查它是否根本没有被触发。我发现在 OnTimer 事件触发后您自己的代码很可能会失败。
  • @jachguate:我相信我真正的问题是内存泄漏。你对此有什么建议吗?
  • @user639464 您可以先在开发环境中运行应用程序一段时间并激活 fastMM 泄漏检测,但这是另一个问题(可能已经在这里回答了)

标签: delphi timer


【解决方案1】:

我敢打赌它会在重启 49 天后停止。当 Windows GetTickCount 环绕时。确定您没有进行基于此会失败的检查?

【讨论】:

  • Erik,TTimer 组件使用 SetTimer() 函数而不是 GetTickCount
  • @RRUZ:是的,这就是为什么我问他是否有支票
  • 我相信我真正的问题是内存泄漏。你对此有什么建议吗?
【解决方案2】:

TTimer 只是 Windows SetTimer() API 的一个包装器,我相信它会永远运行。

我怀疑计时器仍在运行,但它触发的事件处理程序未能按预期运行。

【讨论】:

  • 我相信我真正的问题是内存泄漏。你对此有什么建议吗?
  • 有趣的建议是,一旦你完成了它,就开始释放你的记忆。但是内存泄漏不会导致这样的失败。您是否正遭受资源/句柄/GDI 对象泄漏的困扰?无论如何,您应该提出一个新问题,提供更多信息。
【解决方案3】:

我不知道为什么一个月后它就停止了;我怀疑(正如 Erik 所说)你有一些使用 GetTickCount() 的东西在大约 49 天的环绕后失败了。

不过,作为一般规则,最好停止/启动计时器,以防止延迟导致计时器消息被丢弃:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled := False;
  try
    // Do whatever on timer event firing
  finally
    Timer1.Enabled := True;
  end;
end;

你可以试试这个,而不是让它一直运行;如果它是 TTimer 代码中的错误(在快速扫描 XE 的 TTimer 实现后我没有看到任何东西),停止和启动可能会重置一些东西以防止失败。

【讨论】:

  • 我看不出这有什么帮助。如何丢弃计时器事件?此代码可能会阻止您对计时器事件感到厌烦。但它们不会被丢弃,它们只是被发布到消息队列中。
  • 如果 TTimer 基于 WM_TIMER windows 消息,如果函数耗时过长,多个定时器事件将合并为一个定时器事件。我建议启动和停止计时器只是为了防止 49 天失败!
  • @Gregor 什么 49 天失败?您是否有说明计时器在 49 天后停止的文档?
  • @David 没有任何文档,但是在 OP 建议的时间段(1 个月)内启动和停止计时器将重置“无论什么”停止计时器的可能性都很大。至少它值得一试,但需要一个月或更长时间才能测试:-)
  • @David,不,他们没有。 WM_TIMER 事件的优先级较低,实际上会被丢弃,而不是将多个事件发布到消息队列中。 Raymond Chen 不久前写了一篇关于这个的帖子,我相信......我会尝试挖掘一个链接。
【解决方案4】:

您应该在作业完成后释放分配的内存:

Timer1.FreeOnRelease().Free();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-21
    • 2015-01-13
    • 1970-01-01
    • 2014-02-08
    • 1970-01-01
    • 2020-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多