2011-03-09 54 views
1

我在我的软件中使用TTimer,它应该永远24/7运行。我的软件中没有任何地方是该计时器禁用或停止运行。它的主要功能是更新表格的值。一旦软件运行就开始运行,从那时起,TTimer不应停止。然而,在运行了一个多月之后,TTimer神秘地停止了运行。该软件在Windows 7上运行,该软件是在Delphi 2010 XE上开发的。我搜索了我的代码,看看可能是什么原因造成的,但我无法弄清楚。TTimer本身停止

Timer1.Enabled:=true; 

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

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

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

喜欢的东西:

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

不过,虽然软件仍然在运行,我能够从一个文件 重装我的产品清单回从TList名单,我的软件开始工作像它应该。

我讨厌说最丑陋的程序员最讨厌的词。恐怕我可能有内存泄漏。任何人都这么想?

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

+0

你怎么知道,如果OnTimer事件不再被解雇?我建议你在OnTimer事件的第一行记录一个条目,运行它直到它停止工作所需的时间,并检查它是否完全没有被触发。在OnTimer事件被触发后,我发现你的代码很可能失败了。 – jachguate 2011-03-10 00:13:32

+0

@jachguate:我相信我真正的问题是内存泄漏。你有什么建议吗。 – ThN 2011-03-11 14:01:43

+0

@ user639464您可以先在开发环境中运行应用程序一段时间,然后启动fastMM leak detection,但这是另一个问题(可能已经在此解答) – jachguate 2011-03-11 16:32:50

回答

1

TTimer只是围绕Windows SetTimer() API的封装,我相信它将永远运行。

我怀疑定时器仍在运行,但它触发的事件处理程序无法按需要运行。

+0

我相信我真正的问题是内存泄漏。你有什么建议吗。 – ThN 2011-03-11 14:00:15

+0

这个荒谬的建议是,一旦你完成了它,就开始释放你的记忆。但是内存泄漏不会导致这样的故障。你可能遭受资源/句柄/ GDI对象泄漏?无论如何,你应该用更多的信息来提出一个新的问题。 – 2011-03-11 14:02:35

5

我敢打赌,它在重新启动后的49天停止。当Windows GetTickCount环绕。确定你没有做基于这个失败的支票?

+0

Erik,'TTimer'组件使用SetTimer()函数而不是' GetTickCount'。 – RRUZ 2011-03-09 22:20:51

+2

@RRUZ:是的,这就是为什么我问他是否有检查 – Erik 2011-03-09 22:24:52

+0

我相信我真正的问题是内存泄漏。你有什么建议吗。 – ThN 2011-03-11 14:01:11

0

我不知道为什么它会在一个月后停止;我怀疑(正如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实现的快速扫描后我没有看到任何东西),停止和启动可能会重置事件以防止失败。

+0

我不明白这可能会有什么帮助。定时器事件如何被丢弃?此代码可能会阻止您饱和定时器事件。他们不会被放弃,他们只是被张贴在消息队列中。 – 2011-03-09 23:29:59

+1

如果TTimer基于WM_TIMER窗口消息,那么如果函数花费太长时间,则多个计时器事件将合并为一个计时器事件。我会建议启动和停止计时器,以防止49天的失败! – 2011-03-09 23:33:05

+1

@格雷戈什么49天失败?你有49天后计时器停止的文档吗? – 2011-03-09 23:41:08

0

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

Timer1.FreeOnRelease().Free();