Microsoft KB Archive/842793

= BUG: The Elapsed event of the System.Timers.Timer class is not raised in a Windows service =

Article ID: 842793

Article Last Modified on 5/18/2007

-

APPLIES TO


 * Microsoft .NET Framework 1.1
 * Microsoft .NET Framework 1.0

-





SYMPTOMS
You can use the Microsoft .NET Framework to create a new Microsoft Windows service that contains a System.Timers.Timer object. When you run this new Windows service, the Elapsed event of the System.Timers.Timer class may not be raised.



CAUSE
Note In this section, the System.Timers.Timer object is referred to as the Timer object.

In the event handler for the Elapsed event of the Timer object, if you call the Stop method of the Timer object, the reference to the Timer object is lost. The garbage collector then reclaims the memory that is associated with the Timer object. Later, even if you call the Start method of the Timer object to raise the Elapsed event, the call does not work. The Elapsed event is not raised.



WORKAROUND
To work around this problem, obtain the hotfix in the following Microsoft Knowledge Base article:

900822 FIX: When a .NET Framework based application uses the System.Threading.Timer class, the timer event may not be signaled in the .NET Framework 1.1 S900822

Additionally, use a System.Threading.Timer object instead of the System.Timers.Timer object.



STATUS
Microsoft has confirmed that this is a bug in the Microsoft products that are listed in the &quot;Applies to&quot; section.



Steps to reproduce the behavior
 Start Microsoft Visual Studio .NET. Use Microsoft Visual Basic .NET to create a Windows Service project that is named WinServ1. By default, the Service1.vb file is created. In Solution Explorer, rename Service1.vb as SimpleService.vb. Open the code view of the SimpleService.vb file.  Replace the existing code with the following code: Imports System Imports System.ServiceProcess Imports System.Diagnostics Imports System.Timers

Public Class SimpleService : Inherits ServiceBase

Protected tmrMain As Timer

Public Shared Sub Main ServiceBase.Run(New SimpleService) End Sub

Public Sub New MyBase.New CanPauseAndContinue = True ServiceName = &quot;WinServ1&quot; tmrMain = New Timer End Sub

Protected Overrides Sub OnStart(ByVal args As String) EventLog.WriteEntry(&quot;WinServ1 started&quot;) AddHandler tmrMain.Elapsed, AddressOf tmrMain_Elapsed AddHandler tmrMain.Disposed, AddressOf tmrMain_Disposed tmrMain.Interval = 1000 ' Start raising the Elapsed event. tmrMain.Enabled = True End Sub

Protected Sub tmrMain_Elapsed(ByVal source As Object, ByVal e As ElapsedEventArgs) EventLog.WriteEntry(&quot;WinServ1&quot;) ' Stop raising the Elapsed event. tmrMain.Stop ' Force garbage collection to make sure that the garbage collector ' reclaims the memory that is associated with the tmrMain Timer object. GC.Collect ' Start to raise the Elapsed event again. tmrMain.Start End Sub Protected Sub tmrMain_Disposed(ByVal source As Object, ByVal e As EventArgs) EventLog.WriteEntry(&quot;WinServ1 timer disposed&quot;) End Sub

End Class </li> In Solution Explorer, click SimpleService.vb.</li> On the View menu, click Properties Window to display the Properties window for the SimpleService.vb service.</li> Switch to the design view of the SimpleService.vb service.</li> At the bottom of the Properties window, click the Add Installer link to add the ProjectInstaller.vb file to your project. By default, the ServiceProcessInstaller1 object and the ServiceInstaller1 object are created.</li> In the Properties window for the ServiceInstaller1 object, set the StartType property to Automatic.</li> In the Properties window for the ServiceProcessInstaller1 object, set the Account property to LocalSystem.</li> In Solution Explorer, right-click the WinServ1 project, and then click Properties. The WinServ1 Property Pages dialog box appears.</li> In the Startup object box, select Sub Main, and then click OK.</li> On the Build menu, click Build Solution to create the WinServ1.exe file.</li> Install the Windows service that you created. To do this, run the following command at a Visual Studio .NET command prompt:

installutil \WinServ1.exe

Note  is a placeholder for the absolute file path of the WinServ1.exe file that you created in step 14.</li> Restart your computer.

The WinServ1 service starts to run and then writes information to the application log of Event Viewer every second. You may soon notice that the WinServ1 service does not write information to the application log. This behavior indicates that the Elapsed event is not being raised.</li></ol>

<div class="references_section">