Search code examples
c#timertimeoutintervals

C# wait timeout before calling method and reset timer on consecutive calls


I have a event in my code that can possibly get fired multiple times a second at some moment.

However I would like to implement a way to make that method wait 500ms before really firing, if the method gets called again before those 500ms are over, reset the timer and wait for 500ms again.

Coming from javascript I know this is possible with setTimeout or setInterval. However I'm having trouble figuring out how I could implement such a thing in C#.


Solution

  • You could use a System.Timers.Timer wrapped in a class to get the behaviour you need:

    public class DelayedMethodCaller
    {
        int _delay;
        Timer _timer = new Timer();
    
        public DelayedMethodCaller(int delay)
        {
            _delay = delay;
        }
    
        public void CallMethod(Action action)
        {
            if (!_timer.Enabled)
            {
                _timer = new Timer(_delay)
                {
                    AutoReset = false
                };
                _timer.Elapsed += (object sender, ElapsedEventArgs e) =>
                    {
                        action();
                    };
                _timer.Start();
            }
            else
            {
                _timer.Stop();
                _timer.Start();
            }
        }
    }
    

    This can then be used in the following manner:

    public class Program
    {
        static void HelloWorld(int i)
        {
            Console.WriteLine("Hello World! " + i);
        }
    
        public static void Main(string[] args)
        {
            DelayedMethodCaller methodCaller = new DelayedMethodCaller(500);
            methodCaller.CallMethod(() => HelloWorld(123));
            methodCaller.CallMethod(() => HelloWorld(123));
            while (true)
                ;
        }
    }
    

    If you run the example, you will note that "Hello World! 123" is only displayed once - the second call simply resets the timer.