JS's setInterval and setTimeOut is really convenient. And I want to ask how to implement the same thing in C#.
Asked
Active
Viewed 3.1k times
22
-
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
-
1An 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
-
1Strictly 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 Answers
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
-
As I correct understand correctly this answer: https://stackoverflow.com/a/2311184/647845 timer won't get disposed when it goes out of scope? – Dirk Boer Nov 19 '18 at 10:00
-
1@DirkBoer that's correct, alternatively just keep a reference to it alive – Kevin Smith Nov 19 '18 at 10:11
-
1ahh okay! Good to get double confirmed. Shouldn't the last sentence be changed in this answer then? :) saves people maybe a second lookup for the ones that are doubting. – Dirk Boer Nov 19 '18 at 10:38
-
1
-
5
-
@KevinSmith - Thanks. I thought that was probably the intent. Why not just use while(true)? heh – KWallace Mar 16 '21 at 18:05
-
@KirbyL.Wallace no idea... just preference... fewer keyboard presses – Kevin Smith Mar 17 '21 at 23:45
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