Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there anything wrong with creating a timer for each instance?

Tags:

c#

events

timer

For good understanding I will take a simple abstraction of DHCP lease as example: The lease contains the IP and MAC address, the time it was granted at and can be renewed with a given time span. Once expired an event will be invoked. Again, this is just serving as the most minimal example I could come up with:

using System;
using System.Net;
using System.Net.NetworkInformation;
using System.Timers;

namespace Example
{
    public class Lease
    {
        public IPAddress IP
        {
            get;
            private set;
        }

        public PhysicalAddress MAC
        {
            get;
            private set;
        }

        public DateTime Granted
        {
            get;
            private set;
        }

        public event EventHandler Expired;

        private readonly Timer timer;

        public Lease(IPAddress ip, PhysicalAddress mac, TimeSpan available)
        {
            IP = ip;
            MAC = mac;

            timer = new Timer();
            timer.AutoReset = false;
            timer.Elapsed += timerElapsed;

            Renew(available);
        }

        public void timerElapsed(object sender, EventArgs e)
        {
            var handle = Expired;
            if (handle != null)
            {
                handle(this, EventArgs.Empty);
            }
        }

        public void Renew(TimeSpan available)
        {
            Granted = DateTime.Now;
            timer.Interval = available.TotalMilliseconds;
            timer.Enabled = true;
        }
    }
}

Is there anything to consider when creating - for example - "a few thousand" instances of such a class? I am mostly concerned about the timers. Should I consider another design pattern for such a task (like a manager for all the leases,or not use timers at all?) or is there nothing to worry about when creating a lot of timers, and this is the appropriate way? At least I always try to be cautious when it comes to timers and events.

like image 831
Num Lock Avatar asked Feb 03 '26 18:02

Num Lock


1 Answers

Rather than creating thousands of timers, you could just store the expiration time of each Lease object, then in a single thread query for the expired ones periodically.

An off the top of my head code example:

var leases = new List<Lease>();
var running = true;

var expiredChecker = Task.Factory.StartNew(() =>
{
    while (running)
    {
        var expired = leases.All(l => l.ExpirationDate < DateTime.Now);
        // do something with the expired lease objects
    }
});

Assuming you have an IEnumerable<Lease>, a DateTime property called ExpirationDate on your Lease object, you can then cancel this by setting running to false when you want to stop.

like image 165
Dutts Avatar answered Feb 05 '26 07:02

Dutts



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!