2011-03-09 51 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();