0

I have a program that needs to do something every 60 seconds. Almost always this takes 1-2 seconds to complete but there is a condition whereby it could take a few minutes.

Does anybody know of a .net timer that will not invoke the "time elapsed" method if the previous invocation has not yet completed?

I could obviously do this with a check like this...

if(beingRun){

}

benstpierre
  • 32,833
  • 51
  • 177
  • 288
  • 1
    If the previous invocation hasn't finished, do you still want to run the current invocation (as soon as the previous has finished) or skip it altogther? – Matt Burland Sep 25 '14 at 18:23
  • Why don't you just write a simple program and find out for yourself? It's pretty trivial to write a test program. – Servy Sep 25 '14 at 18:26

3 Answers3

0

You could write an async method to do this:

public async void Recur(Action action, TimeSpan time, CancellationToken token)
{
    while(!token.IsCancellationRequested)
    {
        action();
        try
        {
            await Task.Delay(time, token);
        }
        catch(TaskCancelledException)
        {
            break;
        }
    }
}

and use it like:

CancellationTokenSource cts = new CancellationTokenSource();
Recur(() => DoMyBigJob(), TimeSpan.FromMinutes(1), cts.Token);

and to kill it

cts.Token.Cancel();

Don't lose your CancellationTokenSource, otherwise you'll have a rogue async loop that's out of your control.

spender
  • 117,338
  • 33
  • 229
  • 351
0

I normally just store whether or not the timer should process in a bool, like so:

Timer timer = new Timer();
timer.Elapsed += timer_Elapsed;
timer.Interval = TimeSpan.FromSeconds(60).TotalMiliseconds;

bool processingSomething = false;

void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    if (!processingSomething)
    {
        processingSomething = true;

        // Process stuff here . . .

        processingSomething = false;
    }
}
Rufus L
  • 36,127
  • 5
  • 30
  • 43
0

Use the Enabled property.

using System;
using System.Linq;
using System.Text;
using System.Timers;

namespace ConsoleApplication1
{
    internal class Program
    {
        private static readonly Timer MyTimer = new Timer()
        {
            Interval = 60,
        };

        private static void Main(string[] args)
        {
            MyTimer.Elapsed += MyTimerOnElapsed;
        }

        private static void MyTimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs)
        {
            MyTimer.Enabled = false;

            try
            {
                // Some code here
            }
            finally
            {
                MyTimer.Enabled = true;
            }
        }
    }
}
Joakim
  • 101
  • 4