Define various timers (System.Timers.Timer)

so I have a timer that starts every second. It usually takes only a few milliseconds to start, but sometimes a single timer takes longer than 1 second to execute. This in itself is not a problem, because C # handles different runs on different (or the same) threads, etc.

But what if I want to recognize which method a particular method was triggered is called when 2 runs are running at the same time? I would like to have 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 bogus 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 application (multiple levels).

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

And if I have a static memorable SignalTime, it will be overwritten on every startup.

Any ideas?

+3


source to share


2 answers


Since it is System.Timers.Timer

not sealed, you can 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;
    }
}

      

Insert sender

in TimerWithRunCounter

in a 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++;
    }
}

      

Usage example:

var timer = new TimerWithRunCounter(0, 1000);

      

+1


source


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

The easiest way to achieve this is to keep the counter in the same class with an event handler:

private static int _timerCounter;

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

    GetMainStuff();
    GetMoreMainStuff();
}

      

If every method being called 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 chain of calls in which you want to extensively learn the counter across the entire context, you can either continue with the pattern described above by passing a value down to each called method, or create a "calling context" of the class where you put the code for these methods together with the current value of the counter:

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();
}

      

This way, every method you call that is a member of the class TimerContext

has access to a counter.

These are just a few different approaches you can take. There are other options of course, but hopefully the above gives you some idea of ​​how these options will work (they are all variations of the theme).

+1


source







All Articles