22

JS's setInterval and setTimeOut is really convenient. And I want to ask how to implement the same thing in C#.

Pai
  • 327
  • 1
  • 3
  • 10
  • You can use a `Timer` Class, https://msdn.microsoft.com/en-au/library/system.web.ui.timer.aspx – Aruna Dec 10 '16 at 23:15
  • 1
    An explanation of the actual problem you're trying to solve would help understand which possible alternative you could use in C#, or even if the problem lends itself to be solved using this type of approach. – Luc Morin Dec 10 '16 at 23:15
  • 1
    Strictly speaking, you can't. C# *by itself* cannot do any of the sorts. However, if you're talking about .NET, then there are at least 3 Timer classes: [System.Timers.Timer](https://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx), [System.Threading.Timer](https://msdn.microsoft.com/en-us/library/system.threading.timer(v=vs.110).aspx) and [System.Windows.Forms.Timer](https://msdn.microsoft.com/en-us/library/system.windows.forms.timer(v=vs.110).aspx). – Lasse V. Karlsen Dec 10 '16 at 23:15
  • @LasseV.Karlsen There is another one `System.Web.UI.Timer` at https://msdn.microsoft.com/en-au/library/system.web.ui.timer.aspx – Aruna Dec 10 '16 at 23:17

2 Answers2

39

You can just do a Task.Delay within a Task.Run, try out:

var task = Task.Run(async () => {
                        for(;;)
                        {
                            await Task.Delay(10000)
                            Console.WriteLine("Hello World after 10 seconds")
                        }
                    });

Then You could even wrap this up in to your own SetInterval method that takes in an action

class Program
{
    static void Main(string[] args)
    {
        SetInterval(() => Console.WriteLine("Hello World"), TimeSpan.FromSeconds(2));
        SetInterval(() => Console.WriteLine("Hello Stackoverflow"), TimeSpan.FromSeconds(4));


        Thread.Sleep(TimeSpan.FromMinutes(1));
    }

    public static async Task SetInterval(Action action, TimeSpan timeout)
    {
        await Task.Delay(timeout).ConfigureAwait(false);

        action();

        SetInterval(action, timeout);
    }
}

or you could just use the built in Timer class which practically does the same thing

    static void Main(string[] args)
    {

        var timer1 = new Timer(_ => Console.WriteLine("Hello World"), null, 0, 2000);
        var timer2 = new Timer(_ => Console.WriteLine("Hello Stackoverflow"), null, 0, 4000);


        Thread.Sleep(TimeSpan.FromMinutes(1));
    }

Just make sure you're timers don't go out of scope and get disposed.

.NET 6 Update

.NET 6 introduced a new type called PeriodicTimer this simplifies the above, and can be used like the following:

var timer = new PeriodicTimer(TimeSpan.FromSeconds(10));

while (await timer.WaitForNextTickAsync())
{
    Console.WriteLine("Hello World after 10 seconds")
}

If you need to be able to cancel the timer the WaitForNextTickAsync function has an overload for a cancellation token.

Kevin Smith
  • 13,746
  • 4
  • 52
  • 77
4

Its simply like this, you define an static System.Timers.Timer; then call the function that binds the timer.Elapsed event to your interval function that will be called each X miliseconds.

   public class StaticCache {        
      private static System.Timers.Timer syncTimer;

      StaticCache(){
        SetSyncTimer();
      }
      private void SetSyncTimer(){
        // Create a timer with a five second interval.
        syncTimer = new System.Timers.Timer(5000);

        // Hook up the Elapsed event for the timer. 
        syncTimer.Elapsed += SynchronizeCache;
        syncTimer.AutoReset = true;
        syncTimer.Enabled = true;
     }
     private static void SynchronizeCache(Object source, ElapsedEventArgs e)
     {
        // do this stuff each 5 seconds
     }
    }
JDC
  • 1,569
  • 16
  • 33
MarioAraya
  • 336
  • 5
  • 10