简体   繁体   中英

Identify different timer runs (System.Timers.Timer)

so i have a timer, which runs every second. Mostly it only takes a few milliseconds to run, but sometimes the execution of one timer run, exceeds 1 second. This is in itself not a problem, because c# handles putting the different runs in different (or the same) threads etc.

But what if i want to recognize by which run a certain method was called, when 2 runs are being executed at the same time? I would like to have an output in my console like:

Run 1: Method "GetThisStuff" called
Run 1: Method "GetOtherStuff" called
Run 2: Method "GetThisStuff" called
Run 1: Method "GetFinalStuff" called
Run 2: Method "GetOtherStuff" called
Run 2: Method "GetFinalStuff" called

If i have a timer method

public static void timer_Elapsed(object sender, ElapsedEventArgs e)  {
     GetMainStuff();
     GetMoreMainStuff();

 }

And some dummy methods:

public void GetMainStuff()
{
   GetThisStuff();
   GetOtherStuff();
}

public void GetMoreMainStuff()
{
   GetFinalStuff();
}

I know there is

ElapsedEventArgs.SignalTime

but i don't want to give this as a parameter through every method of my app (down several "levels").

I also know, that not every new run will have a new thread.

And if i have a static remembered SignalTime, it will be overwritten every run.

Any Ideas?

As System.Timers.Timer is not sealed, you could extend it to add a Counter property:

public class TimerWithRunCounter : System.Timers.Timer
{
    public int Counter { get; set; }

    public TimerWithRunCounter(int counter, double interval) : base(interval)
    {
        Counter = counter;
    }
}

Cast sender to TimerWithRunCounter in the timer callback and access and increment the counter:

public static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    var timer = (TimerWithRunCounter)sender;
    lock (lockObject)
    {
        Console.WriteLine("Run {0}", timer.Counter);
        timer.Counter++;
    }
}

Example usage:

var timer = new TimerWithRunCounter(0, 1000);

Do you need the methods themselves to know the context? Or do you just need to know in the event handler?

The simplest way to accomplish this is to maintain a counter in the same class with the event handler:

private static int _timerCounter;

public static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    int counter = Interlocked.Increment(ref _timerCounter);

    GetMainStuff();
    GetMoreMainStuff();
}

If each called method needs to know this value, then of course you can pass the value:

public static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    int counter = Interlocked.Increment(ref _timerCounter);

    GetMainStuff(counter);
    GetMoreMainStuff(counter);
}

If you have a deep call chain in which you want to broadly know the counter throughout the context, then you can either continue the above pattern, passing the value on down into each called method, or you can create a "calling context" class, into which you put the code for those methods, along with the current counter's value:

class TimerContext
{
    private readonly int _timerCount;
    public int TimerCount { get { return _timerCount; } }

    public TimerContext(int timerCount)
    {
        _timerCount = timerCount;
    }

    public void GetMainStuff()
    {
        GetThisStuff();
        GetOtherStuff();
    }

    public void GetMoreMainStuff()
    {
        GetFinalStuff();
    }

    // etc.
}

public static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    TimerContext context = new TimerContext(Interlocked.Increment(ref _timerCounter));

    context.GetMainStuff();
    context.GetMoreMainStuff();
}

In that way, every single method you call, being a member of the TimerContext class, has access to the counter.

Those are just a few different approaches you can take. Of course, there are other options but hopefully the above gives you some idea of how those options would work (they are all variations on the theme).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM