Tom
Tom

Reputation: 33

Execute a function ever 60 seconds

I want to execute a function every 60 seconds in C#. I could use the Timer class like so:

timer1 = new Timer();
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = 60 * 1000; // in miliseconds
timer1.Start();

Question is I have a long running process. Occasionally it make take several minutes. Is there a way to make the timer smart so if the function is already being executed then it should skip that cycle and come back 60 seconds later and if again it is in execution then again skip and come back 60 seconds later.

Upvotes: 1

Views: 1792

Answers (4)

fym
fym

Reputation: 41

Use a timer, set it to 60 second

On Event:

try
  Stop timer
  Do logic
catch
  What ever fail recovery 
finally
  Start the timer

Logic is run 60 seconds after last finish.

Upvotes: 1

Vivek Nuna
Vivek Nuna

Reputation: 1

I would suggest you to have a class member variable bool variable with value false.

then in click event return if its true at the beginning.

and then set it to true, so that it will tell you that its currently in execution.

then write your logic.

and then once done finally set it to false again.

code will look like this.

private bool isRunning = false;

private void timer1_Tick(object sender, EventArgs e)
{
    if (isRunning)
    {
        return;
    }

    isRunning = true;
    
    try
    {
        ... //Do whatever you want 
    }
    finally
    {
        isRunning = false;
    }
}

Upvotes: 4

Mafii
Mafii

Reputation: 7425

The modern and most clean way to do this is using Microsoft's new Period Timer:

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

while (await timer.WaitForNextTickAsync())
{
    //Business logic
}

If you need to abort such a ticker, you can pass a cancellation token to the WaitForNextTickAsync method.

Another advantage is this:

The PeriodicTimer behaves like an auto-reset event, in that multiple ticks are coalesced into a single tick if they occur between calls to WaitForNextTickAsync(CancellationToken). Similarly, a call to Dispose() will void any tick not yet consumed. WaitForNextTickAsync(CancellationToken) may only be used by one consumer at a time, and may be used concurrently with a single call to Dispose().

Source: https://learn.microsoft.com/en-us/dotnet/api/system.threading.periodictimer.waitfornexttickasync?source=recommendations&view=net-7.0#remarks


If you need more granularity (like "always at 10 am", use something like https://github.com/HangfireIO/Cronos

Upvotes: 3

Manuel Fabbri
Manuel Fabbri

Reputation: 568

You can use a Stopwatch inside a loop: start the stopwatch, after 60 second call the function, reset the stopwatch, start the loop again.

Upvotes: -2

Related Questions