Solved

Disable and re-enable a dynamic System.Timers.Timer

Posted on 2016-11-21
6
42 Views
Last Modified: 2016-11-23
Hello,

We have a windows service that creates several timers dynamically.

They execute every 20 seconds. sometimes this is enough time to do the processing, sometimes not.

So, we would like to be able to disable the timer, then re-enable it after processing has finished.

I tried creating a global list of timers and adding each timer to the list, then setting the properties, but this did not work.

All input is greatly appreciated.

resourcesys.
0
Comment
Question by:resourcesys
  • 3
  • 2
6 Comments
 
LVL 62

Expert Comment

by:Fernando Soto
ID: 41896140
Please post your code so we can see what you are working with so we can suggest some solutions.
0
 

Author Comment

by:resourcesys
ID: 41896186
Hello Fernando,

Firstly, using a repository object we get a list of classes (machine)

        Dim lstMachines As List(Of Machine) = objMachiness.GetMachines()

        For i As Integer = 0 To lstMachines.Count - 1
            Dim objTimer As New CustomTimer
            objTimer.MachineObject = lstMachines.Item(i)
            objTimer.Interval = 20000
            AddHandler objTimer.Elapsed, AddressOf Timer_Elapsed
            objTimer.Enabled = True
        Next

Open in new window


Then we have the method that carries out the processing:

    Private Sub Timer_Elapsed(ByVal sender As System.Object, ByVal e As System.Timers.ElapsedEventArgs)
        Dim objTimer As CustomerTimer = DirectCast(sender, CustomTimer)
        'Processing here
    End Sub

Open in new window


It's as simple as that.

I have tried disabling objTimer but that doesn't work it seems to disable all timers?

Thanks.

resourcesys
0
 
LVL 33

Expert Comment

by:it_saige
ID: 41896286
You probably want to implement a timer on each Machine object instead; e.g. -
Imports System.Timers

Module Module1
	Private machines As List(Of Machine)

	Sub Main()
		machines = (From i In Enumerable.Range(1, 20) Select New Machine() With {.ID = i, .Name = String.Format("Machine{0}", i), .CustomTimer = New Timer(i * 200)}).ToList()
		For Each [machine] As Machine In machines
			AddHandler [machine].TimerElapsed, AddressOf OnTimerElapsed
			Console.WriteLine("Starting the timer for {0}", [machine].Name)
			[machine].CustomTimer.Start()
		Next
		Console.ReadLine()
	End Sub

	Private Sub OnTimerElapsed(ByVal sender As Object, ByVal e As ElapsedEventArgs)
		If TypeOf sender Is Machine Then
			Dim m = DirectCast(sender, Machine)
			m.CustomTimer.Enabled = False
			Console.WriteLine("Stopping the timer for {0}", m.Name)
		End If
	End Sub
End Module

Class Machine
	Private ReadOnly fTimerElapsed As New List(Of ElapsedEventHandler)
	Public Custom Event TimerElapsed As ElapsedEventHandler
		AddHandler(value As ElapsedEventHandler)
			fTimerElapsed.Add(value)
		End AddHandler

		RemoveHandler(value As ElapsedEventHandler)
			fTimerElapsed.Remove(value)
		End RemoveHandler

		RaiseEvent(sender As Object, e As ElapsedEventArgs)
			For Each handler In fTimerElapsed
				Try
					handler.Invoke(sender, e)
				Catch ex As Exception
					Debug.WriteLine(String.Format("Exception while invoking event handler: {0}", ex))
				End Try
			Next
		End RaiseEvent
	End Event

	Private _customTimer As Timer

	Public Property ID() As Integer
	Public Property Name() As String

	Public Property CustomTimer() As Timer
		Get
			Return _customTimer
		End Get
		Set(ByVal value As Timer)
			_customTimer = value
			If _customTimer IsNot Nothing Then
				AddHandler _customTimer.Elapsed, AddressOf OnTimerElapsed
			End If
		End Set
	End Property

	Private Sub OnTimerElapsed(ByVal sender As Object, ByVal e As ElapsedEventArgs)
		RaiseEvent TimerElapsed(Me, e)
	End Sub
End Class

Open in new window

Which produces the following output -Capture.JPG
-saige-
0
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 

Author Comment

by:resourcesys
ID: 41897273
Hello it_saige,

Thank you for your response.

This looks promising, so I will do some testing of my own and give you feedback on how it goes.

Thanks.

resourcesys
0
 
LVL 33

Accepted Solution

by:
it_saige earned 500 total points
ID: 41897459
You will probably want to shore some of this up in order to make it more securable.  In all honesty, I would even question the validity of having the timer object as a publicly settable property.  I would see about using a constructor to pass the interval and move the logic for handler adding to that constructor; e.g. -
Imports System.Timers

Module Module1
	Private machines As List(Of Machine)

	Sub Main()
		machines = (From i In Enumerable.Range(1, 20) Select New Machine(i * 200) With {.ID = i, .Name = String.Format("Machine{0}", i)}).ToList()
		For Each [machine] As Machine In machines
			AddHandler [machine].TimerElapsed, AddressOf OnTimerElapsed
			Console.WriteLine("Starting the timer for {0}", [machine].Name)
			[machine].CustomTimer.Start()
		Next
		Console.ReadLine()
	End Sub

	Private Sub OnTimerElapsed(ByVal sender As Object, ByVal e As ElapsedEventArgs)
		If TypeOf sender Is Machine Then
			Dim m = DirectCast(sender, Machine)
			m.CustomTimer.Enabled = False
			Console.WriteLine("Stopping the timer for {0}", m.Name)
		End If
	End Sub
End Module

Class Machine
	Private ReadOnly fTimerElapsed As New List(Of ElapsedEventHandler)
	Public Custom Event TimerElapsed As ElapsedEventHandler
		AddHandler(value As ElapsedEventHandler)
			fTimerElapsed.Add(value)
		End AddHandler

		RemoveHandler(value As ElapsedEventHandler)
			fTimerElapsed.Remove(value)
		End RemoveHandler

		RaiseEvent(sender As Object, e As ElapsedEventArgs)
			For Each handler In fTimerElapsed
				Try
					handler.Invoke(sender, e)
				Catch ex As Exception
					Debug.WriteLine(String.Format("Exception while invoking event handler: {0}", ex))
				End Try
			Next
		End RaiseEvent
	End Event

	Private _customTimer As Timer
	Public Property ID() As Integer
	Public Property Name() As String
	Public Property CustomTimer() As Timer
		Get
			Return _customTimer
		End Get
		Private Set(value As Timer)
			If value IsNot Nothing AndAlso Not value.Equals(_customTimer) Then
				_customTimer = value
			End If
		End Set
	End Property

	Public Sub New(Optional interval As Double = 20)
		CustomTimer = New Timer(interval)
		AddHandler CustomTimer.Elapsed, AddressOf OnTimerElapsed
	End Sub

	Private Sub OnTimerElapsed(ByVal sender As Object, ByVal e As ElapsedEventArgs)
		RaiseEvent TimerElapsed(Me, e)
	End Sub
End Class

Open in new window


Which produces the same output as above.

-saige-
0
 

Author Closing Comment

by:resourcesys
ID: 41899423
Thanks it_saige, it worked great.

resourcesys.
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
Migrating to Microsoft Office 365 is becoming increasingly popular for organizations both large and small. If you have made the leap to Microsoft’s cloud platform, you know that you will need to create a corporate email signature for your Office 365…
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.

863 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

28 Experts available now in Live!

Get 1:1 Help Now