Windows Service Timer Woes

  • Thread starter John David Thornton
  • Start date
J

John David Thornton

I've got a Windows Service class, and I put a System.Threading.Timer, and
I've coded it as shown below. However, when I install the service and then
start it in MMC, I get a peculiar message:

The MyService service on Local Computer started and then stopped. Some
services stop automatically if they ahve no work to do, for example, the
Perforamnce Logs and Alert service.

I tried switching to a System.Threading.Timer and that didn't work either.

Can someone please tell me what I'm doing wrong here?

Thanks

Imports System.ServiceProcess
Imports System.Timers

Public Class Service
Inherits System.ServiceProcess.ServiceBase

#Region " Component Designer generated code "

Public Sub New()
MyBase.New()

' This call is required by the Component Designer.
InitializeComponent()

' Add any initialization after the InitializeComponent() call
' Create the delegate that invokes methods for the timer.
End Sub


'UserService overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

' The main entry point for the process
<MTAThread()> _
Shared Sub Main()
Dim ServicesToRun() As System.ServiceProcess.ServiceBase

' More than one NT Service may run within the same process. To add
' another service to this process, change the following line to
' create a second service object. For example,
'
' ServicesToRun = New System.ServiceProcess.ServiceBase () {New
Service1, New MySecondUserService}
'
ServicesToRun = New System.ServiceProcess.ServiceBase() {New
Service}

System.ServiceProcess.ServiceBase.Run(ServicesToRun)

End Sub

'Required by the Component Designer
Private components As System.ComponentModel.IContainer

' NOTE: The following procedure is required by the Component Designer
' It can be modified using the Component Designer.
' Do not modify it using the code editor.
Friend WithEvents timer As System.Timers.Timer
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
Me.timer = New System.Timers.Timer
CType(Me.timer,
System.ComponentModel.ISupportInitialize).BeginInit()
'
'timer
'
Me.timer.Enabled = True
'
'Service
'
Me.ServiceName = "DrugScreen.com Batch Processing Service"
CType(Me.timer, System.ComponentModel.ISupportInitialize).EndInit()

End Sub

#End Region

Protected Overrides Sub OnStart(ByVal args() As String)

Const LogName As String = "SECON Batch Processor"
Const SourceName As String = "SECON Batch Processor"
Const FiveMinutes As Integer = 300000

If Not EventLog.SourceExists(SourceName) Then
EventLog.CreateEventSource(SourceName, LogName)
End If

EventLog.WriteEntry("Service started.",
EventLogEntryType.Information)

' Immediately process any pending work
BatchProcessor.ProcessBatch()

timer.Interval = FiveMinutes
timer.Enabled = True
timer.Start()

End Sub

Protected Overrides Sub OnStop()
timer.Stop()
timer.Dispose()
timer = Nothing
End Sub

Protected Overrides Sub OnPause()
timer.Enabled = False
EventLog.WriteEntry("Service paused.",
EventLogEntryType.Information)
End Sub

Protected Overrides Sub OnContinue()
timer.Enabled = True
EventLog.WriteEntry("Service resumed.",
EventLogEntryType.Information)
End Sub

Private Sub timer_Elapsed(ByVal sender As Object, ByVal e As
System.Timers.ElapsedEventArgs) Handles timer.Elapsed
BatchProcessor.ProcessBatch()
End Sub

End Class
 
T

Tom Shelton

I've got a Windows Service class, and I put a System.Threading.Timer, and
I've coded it as shown below. However, when I install the service and then
start it in MMC, I get a peculiar message:

The MyService service on Local Computer started and then stopped. Some
services stop automatically if they ahve no work to do, for example, the
Perforamnce Logs and Alert service.

I tried switching to a System.Threading.Timer and that didn't work either.

Can someone please tell me what I'm doing wrong here?

Thanks

Imports System.ServiceProcess
Imports System.Timers

Public Class Service
Inherits System.ServiceProcess.ServiceBase

#Region " Component Designer generated code "

Public Sub New()
MyBase.New()

' This call is required by the Component Designer.
InitializeComponent()

' Add any initialization after the InitializeComponent() call
' Create the delegate that invokes methods for the timer.
End Sub


'UserService overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

' The main entry point for the process
<MTAThread()> _
Shared Sub Main()
Dim ServicesToRun() As System.ServiceProcess.ServiceBase

' More than one NT Service may run within the same process. To add
' another service to this process, change the following line to
' create a second service object. For example,
'
' ServicesToRun = New System.ServiceProcess.ServiceBase () {New
Service1, New MySecondUserService}
'
ServicesToRun = New System.ServiceProcess.ServiceBase() {New
Service}

System.ServiceProcess.ServiceBase.Run(ServicesToRun)

End Sub

'Required by the Component Designer
Private components As System.ComponentModel.IContainer

' NOTE: The following procedure is required by the Component Designer
' It can be modified using the Component Designer.
' Do not modify it using the code editor.
Friend WithEvents timer As System.Timers.Timer
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
Me.timer = New System.Timers.Timer
CType(Me.timer,
System.ComponentModel.ISupportInitialize).BeginInit()
'
'timer
'
Me.timer.Enabled = True
'
'Service
'
Me.ServiceName = "DrugScreen.com Batch Processing Service"
CType(Me.timer, System.ComponentModel.ISupportInitialize).EndInit()

End Sub

#End Region

Protected Overrides Sub OnStart(ByVal args() As String)

Const LogName As String = "SECON Batch Processor"
Const SourceName As String = "SECON Batch Processor"
Const FiveMinutes As Integer = 300000

If Not EventLog.SourceExists(SourceName) Then
EventLog.CreateEventSource(SourceName, LogName)
End If

EventLog.WriteEntry("Service started.",
EventLogEntryType.Information)

' Immediately process any pending work
BatchProcessor.ProcessBatch()

timer.Interval = FiveMinutes
timer.Enabled = True
timer.Start()

End Sub

Protected Overrides Sub OnStop()
timer.Stop()
timer.Dispose()
timer = Nothing
End Sub

Protected Overrides Sub OnPause()
timer.Enabled = False
EventLog.WriteEntry("Service paused.",
EventLogEntryType.Information)
End Sub

Protected Overrides Sub OnContinue()
timer.Enabled = True
EventLog.WriteEntry("Service resumed.",
EventLogEntryType.Information)
End Sub

Private Sub timer_Elapsed(ByVal sender As Object, ByVal e As
System.Timers.ElapsedEventArgs) Handles timer.Elapsed
BatchProcessor.ProcessBatch()
End Sub

End Class





----------------------------------------------------------

----------------------------------------------------------
color]

John... I think you need to redesign a bit. I expect that, just
calling the start is not enough to keep the process alive.

What I would do is start a worker thread from the onstart. Then you
could handle the timer from there. It would look something like:

Private waitObject As New ManualResetEvent (False)

Protected Overrides Sub OnStart(ByVal args() As String)
Dim worker As New Thread (AddressOf Me.WorkProc)
worker.Start ()
End Sub

Private Sub WorkProc ()
' imediately process any initial work work
BatchProcessor.ProcessBatch()

' set up the timer
timer.Interval = FiveMinutes
timer.AutoReset = False
timer.Enabled = False

do while (processing)
timer.Start ()
waitObject.WaitOne ()
BatchProcessor.ProcessBatch()
waitObject.Reset ()
loop

End Sub

Private Sub timer_Elapsed(ByVal sender As Object, ByVal e As
timer.Enabled
waitObject.Set ()
End Sub

Anyway, that is a basic, obviously air-code example, but hopefully that
will get you started.
 
J

John David Thornton

Thank you very much! That solution worked beautifully!

Tom Shelton said:
I've got a Windows Service class, and I put a System.Threading.Timer, and
I've coded it as shown below. However, when I install the service and
then
start it in MMC, I get a peculiar message:

The MyService service on Local Computer started and then stopped. Some
services stop automatically if they ahve no work to do, for example, the
Perforamnce Logs and Alert service.

I tried switching to a System.Threading.Timer and that didn't work
either.

Can someone please tell me what I'm doing wrong here?

Thanks

Imports System.ServiceProcess
Imports System.Timers

Public Class Service
Inherits System.ServiceProcess.ServiceBase

#Region " Component Designer generated code "

Public Sub New()
MyBase.New()

' This call is required by the Component Designer.
InitializeComponent()

' Add any initialization after the InitializeComponent() call
' Create the delegate that invokes methods for the timer.
End Sub


'UserService overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

' The main entry point for the process
<MTAThread()> _
Shared Sub Main()
Dim ServicesToRun() As System.ServiceProcess.ServiceBase

' More than one NT Service may run within the same process. To
add
' another service to this process, change the following line to
' create a second service object. For example,
'
' ServicesToRun = New System.ServiceProcess.ServiceBase () {New
Service1, New MySecondUserService}
'
ServicesToRun = New System.ServiceProcess.ServiceBase() {New
Service}

System.ServiceProcess.ServiceBase.Run(ServicesToRun)

End Sub

'Required by the Component Designer
Private components As System.ComponentModel.IContainer

' NOTE: The following procedure is required by the Component Designer
' It can be modified using the Component Designer.
' Do not modify it using the code editor.
Friend WithEvents timer As System.Timers.Timer
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
Me.timer = New System.Timers.Timer
CType(Me.timer,
System.ComponentModel.ISupportInitialize).BeginInit()
'
'timer
'
Me.timer.Enabled = True
'
'Service
'
Me.ServiceName = "DrugScreen.com Batch Processing Service"
CType(Me.timer,
System.ComponentModel.ISupportInitialize).EndInit()

End Sub

#End Region

Protected Overrides Sub OnStart(ByVal args() As String)

Const LogName As String = "SECON Batch Processor"
Const SourceName As String = "SECON Batch Processor"
Const FiveMinutes As Integer = 300000

If Not EventLog.SourceExists(SourceName) Then
EventLog.CreateEventSource(SourceName, LogName)
End If

EventLog.WriteEntry("Service started.",
EventLogEntryType.Information)

' Immediately process any pending work
BatchProcessor.ProcessBatch()

timer.Interval = FiveMinutes
timer.Enabled = True
timer.Start()

End Sub

Protected Overrides Sub OnStop()
timer.Stop()
timer.Dispose()
timer = Nothing
End Sub

Protected Overrides Sub OnPause()
timer.Enabled = False
EventLog.WriteEntry("Service paused.",
EventLogEntryType.Information)
End Sub

Protected Overrides Sub OnContinue()
timer.Enabled = True
EventLog.WriteEntry("Service resumed.",
EventLogEntryType.Information)
End Sub

Private Sub timer_Elapsed(ByVal sender As Object, ByVal e As
System.Timers.ElapsedEventArgs) Handles timer.Elapsed
BatchProcessor.ProcessBatch()
End Sub

End Class





----------------------------------------------------------

----------------------------------------------------------
color]

John... I think you need to redesign a bit. I expect that, just
calling the start is not enough to keep the process alive.

What I would do is start a worker thread from the onstart. Then you
could handle the timer from there. It would look something like:

Private waitObject As New ManualResetEvent (False)

Protected Overrides Sub OnStart(ByVal args() As String)
Dim worker As New Thread (AddressOf Me.WorkProc)
worker.Start ()
End Sub

Private Sub WorkProc ()
' imediately process any initial work work
BatchProcessor.ProcessBatch()

' set up the timer
timer.Interval = FiveMinutes
timer.AutoReset = False
timer.Enabled = False

do while (processing)
timer.Start ()
waitObject.WaitOne ()
BatchProcessor.ProcessBatch()
waitObject.Reset ()
loop

End Sub

Private Sub timer_Elapsed(ByVal sender As Object, ByVal e As
timer.Enabled
waitObject.Set ()
End Sub

Anyway, that is a basic, obviously air-code example, but hopefully that
will get you started.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top