Resolved AddHandler Troubles

Vertraag

Member
Joined
Jan 1, 2009
Messages
10
Programming Experience
3-5
Hello,

I am trying to use AddHandler to designate an array of timers to call a function when they have elapsed.

Below is my code:

VB.NET:
Public Shared Sub CreateCooldown(ByVal name As String, ByVal duration As Integer, ByVal timetype As String)

        cooldowns(a).Name = name
        cooldowns(a).Timer = New Timers.Timer
        With cooldowns(a).Timer
            .Enabled = True
            .Interval = 5000 ' An arbitrary value for this example
        End With

            AddHandler cooldowns(a).Timer.Elapsed, cd_Tick(cooldowns(a).Name)
            cooldowns(a).Timer.Start()
        ReDim Preserve cooldowns(cooldowns.Length)
End Sub

    Public Shared Function cd_Tick(ByVal name As String)
        ' Do stuff here
        Return Nothing
    End Function

Unfortunately, when the AddHandler line is called, it instantly fires the cd_Tick function (which I do not want to happen until the timer has elapsed), then never fires it again. Does anyone know why this would be happening?
 
Last edited:
The tick event cannot be a function. It has an event signature that must be maintained. Each timer can have the same tick event, you will use the sender object in the signature to find out which timer is calling. The addhandler should look like this:
VB.NET:
AddHandler cooldowns(a).Timer.Elapsed, AddressOf cd_Tick

'the tick event:

Private Sub cd_Tick(ByVal sender As Object, ByVal e As System.EventArgs)
   CType(sender, Timer) '<- this is the timer in question
End Sub
 
Hi newguy,

Thank you for your help. However, I still have 2 questions:

1) Using your code, is there a way to determine the array index the timer is located in?

2) If I use the following code...

VB.NET:
Dim t = CType(sender, Timer)
t.Stop()

It does not stop the timer in question. Any ideas?

Thanks again.
 
When you created the array of timers you would have to loop thru them and add the event to each timer, did you do that?
 
Yes, but when the event "ticks", how do I let the program know which timer did the ticking? The array is actually an array of a structure, and the timers are only a part of that structure, so I need to figure out a way to obtain the index of the array's timer that ticked. Hope that makes sense.
 
Lets see the Structure and could you explain better what you are trying to accomplish with each timer.
 
Cooldown Structure:
VB.NET:
    Structure CooldownStruct
        Dim Name As String ' This is the name of the cooldown
        Dim Duration As Integer ' This is what we'll set the interval to
        Dim Timer As Timer ' This is a timer
    End Structure

I have created an array of CooldownStruct.

I am using a function called CreateCooldown that adds 1 extra CooldownStruct element to the array, and starts the timer based on the given duration/interval. The "name" parameter simply allows me to identify each cooldown in the array.

When the timer ticks, I have a function called RemoveCooldown that stops the timer and removes that element from the array.

My problem is, when the event fires, I do not know how to identify which timer ticked. Therefore, it would be nice if I could figure out what the index of the array is that holds the timer that ticked.
 
Ok, I got that part, but what exactly do the timers do? What I mean is if you had the index would the code be? What would it do different from the other cooldowns, or is it different? Also I prefer a List(Of T) over an array - the benefits are .Add/.Remove/.RemoveAt method make adding and removing easier - they are a great addition to your toolbox.
 
The index would be used as a parameter for my RemoveCooldown function, since otherwise it will not know which element to remove. Each cooldown will have a different duration, which is why that is important.

Thanks again for all your help so far.
 
In this example I use a listbox names lsb1 just to show them adding and removing. I prefer classes to structures. Does this make sense?
VB.NET:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    For i As Integer = 1 To 4
      makeCooldown(i)
    Next
End Sub
Private cds As New List(Of CooldownStruct)
Private Sub makeCooldown(ByVal index As Integer)
    Dim cd As New CooldownStruct
    'hold the object cd in the timers tag property now we can get it back later
    cd.Timer.Tag = cd
    cd.Timer.Interval = 5000
    cd.Name = index.ToString
    AddHandler cd.Timer.Tick, AddressOf cd_Tick
    cd.Timer.Enabled = True
    cds.Add(cd)
    lsb1.Items.Add(cd.Name)
    Threading.Thread.Sleep(500)
End Sub
Private Sub cd_Tick(ByVal sender As Object, ByVal e As EventArgs)
    'here is where we get the object back
    Dim cd As CooldownStruct = CType(sender, Timer).Tag
    cds.Remove(cd)
    Debug.WriteLine(cd)
    lsb1.Items.Remove(cd.Name)
End Sub
Public Class CooldownStruct
    Public Name As String
    Public Timer As New Timer
End Class
 
Back
Top