Thursday, September 25, 2008

Timer on a new thread attached to a windows service disappears after 10 minutes

I created a visual basic windows service application in Visual Studio 2005 which needed a timer to fire every 10 seconds. I found an example showing how to attach a timer in a new thread to the service which worked fine during development.

Then I installed on a test system and the timer would fire for 10 minutes and then disappear and the service would stop working. Stopping consistently at ten minutes was a clue.

There was no succinct explanation, but Garbage Collection came up in reference to unattended threads. The timer on a new thread was eligible for GC if it was not referenced periodically. The solution was simple, make the timer handle a global variable, and referencing the handle each time the timer handler invokes.

Public Class My_Scheduler_Service

Dim tDelegate As Threading.TimerCallback
Dim oTimer As System.Threading.Timer

Protected Overrides Sub OnStart(ByVal args() As String)
.....
tDelegate = AddressOf TimerFireEvent ' my timer handler
oTimer = New System.Threading.Timer(tDelegate, Me, 0, iTIME_INTERVAL)

end sub

Public Sub TimerFireEvent(ByVal sender As Object)

Try
'reference timer to avoid Garbage Collection
If (oTimer Is Nothing) Then
System.IO.File.AppendAllText("C:\Log.txt", Now.ToString() & ": oTimer = nothing" & vbCrLf)
Else
System.IO.File.AppendAllText("C:\Log.txt", Now.ToString() & ": oTimer OK" & vbCrLf)
End If
...

Posting this because Garbage collection impact on a new timer thread was not something I saw clearly in documentation or examples.

No comments: