Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Proper way of periodically firing functions

Tags:

c#

timing

timer

I've got about 20 functions, some of them should be fired once a second, some, 20 times a second and other twice a minute currently I have something like this:

                DateTime nowVar = DateTime.Now;
                var lastExecutionFunc1 = nowVar;
                var lastExecutionFunc2 = nowVar;
                var lastExecutionFunc3 = nowVar;
                var lastExecutionFunc4 = nowVar;

        DateTime _now = DateTime.Now;


                if ((_now - lastExecutionFunc1).TotalSeconds >= 0.1)
                        {
                            lastExecutionFunc1 = _now;
                            //dosomething
                        }
               if ((_now - lastExecutionFunc2).TotalSeconds >= 0.5)
                        {
                            lastExecutionFunc2 = _now;
                            //do something else
                        }
               if ((_now - lastExecutionFunc3).TotalSeconds >= 30)
                        {
                            lastExecutionFunc3 = _now;
                            //do something else
                        }
.....

While this works, I can't help but think that there should be a more elegant way of doing this. Creating a var to store each execution makes the core look really messy. Guess I could use pair, but that wouldn't be too nice either.

Any advice?

EDIT: If you want to see what I'm trying to accomplish, you can see the whole code here. At line 525.

like image 398
flanker Avatar asked Mar 13 '23 05:03

flanker


1 Answers

Below code presents a basic scheduler with synchronisation lock.

using System;
using System.Collections.Generic;
using System.Timers;

namespace TimerUsage
{
    class Program
    {
        static void Main(string[] args)
        {
            Scheduler scheduler = new Scheduler();
            scheduler.ScheduleMethod(100, () => Console.WriteLine("func1"));
            scheduler.ScheduleMethod(200, () => Console.WriteLine("func2"));
            scheduler.ScheduleMethod(300, () => Console.WriteLine("func3"));
            scheduler.ScheduleMethod(1000, () => Console.WriteLine("func4"));
            scheduler.Run();
            System.Threading.Thread.Sleep(10000);
        }

    }

    public class Scheduler
    {
        private Dictionary<int, Row> _schedule = new Dictionary<int, Row>();

        public void ScheduleMethod(int interval, Action method)
        {
            Row row;
            if (!_schedule.TryGetValue(interval, out row))
            {
                row = new Row(interval);
                _schedule[interval] = row;
            }
            row.AddMethod(method);
        }

        public void Run()
        {
            foreach (var item in _schedule)
            {
                item.Value.StartTimer();
            }
        }
    }

    internal class Row
    {
        private object _syncLock = new object();
        private Timer _timer;
        private List<Action> _methods = new List<Action>();

        public Row(int interval)
        {
            _timer = new System.Timers.Timer(interval);
            _timer.Elapsed += ExecuteItems;
        }

        private void ExecuteItems(object sender, ElapsedEventArgs e)
        {
            lock (_syncLock)
            {
                foreach (var method in _methods)
                {
                    method();
                }
            }
        }

        public void AddMethod(Action method)
        {
            _methods.Add(method);
        }

        public void StartTimer()
        {
            _timer.Start();
        }

    }

}
like image 125
Abdullah Nehir Avatar answered Mar 24 '23 01:03

Abdullah Nehir