-1

I got several devices which send a TCP or POST message each minute. I need to alarm whenever a device stop sending messages after one hour.

I thought about creating one Timer for each device and restarting it whenever a message is received. If the event triggers, call a method with the corresponding ID of the device associated to the timer and generate the alert.

The problem is that I can't find a way to pass fixed parameters to the Timers. Every method I tried somehow the chosen parameter gets replaced the same for every timer.

Is there a better approach? Or which is the correct way to pass parameters to the elapsed event of the timer?

Thanks,

Edit:

This code prints always 5, I need it to print 1 2 3 4 5 (doesn't matter the order)

    private Timer[] timers = new Timer[5];
    private void button6_Click(object sendera, EventArgs ee)
    {
        for (int i = 0; i < timers.Length; i++)
        {
            timers[i] = new Timer(1000);
            timers[i].Elapsed += (sender, e) => { HandleTimerElapsed(i); };
            timers[i].Start();
        }
    }

    static void HandleTimerElapsed(int i)
    {
        Console.WriteLine(i);
    }
Vallo
  • 1,827
  • 2
  • 21
  • 42
  • We cant tell you how to fix code we cant see. – Ňɏssa Pøngjǣrdenlarp Sep 21 '17 at 18:55
  • ok I'll edit soon – Vallo Sep 21 '17 at 19:01
  • edited, that should make it clearer – Vallo Sep 21 '17 at 19:12
  • You dont need multiple timers firing at identical intervals to do the same thing. Create a list of `Foo` items to track which things are active the shut off time etc. When The Timer fires iterate the list and call the ShutOff method passing the relevant id if it is time to stop and it is still active – Ňɏssa Pøngjǣrdenlarp Sep 21 '17 at 19:17
  • I don't follow you. My approach is 1 timer per device, and when it triggers the event it means the device hasn't sent a message for the specified time. Could you detail yours a bit more? thanks – Vallo Sep 21 '17 at 19:19
  • Rather than an array of timers, think of it as a list of ThingsToTurnOff. Each thing would have a shutoff time. When the timer goes off, shut off any of them where the time has expired – Ňɏssa Pøngjǣrdenlarp Sep 21 '17 at 19:26

1 Answers1

1

This happens because the lambda passed to Elapsed closes over i from the for loop. That means that the timer's callback uses the last value of i, which is 5 in that particular situation . You can bypass that by declaring an additional variable inside the loop:

private void button6_Click(object sendera, EventArgs ee)
{
    for (int i = 0; i < timers.Length; i++)
    {
        int temp = i;
        timers[temp] = new Timer(1000);
        timers[temp].Elapsed += (sender, e) => { HandleTimerElapsed(temp); };
        timers[temp].Start();
    }
}
Jakub Dąbek
  • 1,044
  • 1
  • 8
  • 17