Mahmoud Elbably
Mahmoud Elbably

Reputation: 139

C# Timer Callback to use returned value from a function every loop

I want to achieve something that i don't know if its possible, but there goes nothing...

i have a static int variable called X, and a function that increments X then returns the new value.

 public static int X;

 public int ReturnInt()
    {
        X = X + 1
        return x;
    }

i have another function which is a TimerCallBack function that will be looped over every N milliseconds.

public static void TimerCallback(Object o)
    {
        y = ReturnInt();
        Console.WriteLine("Value:" + y);
        GC.Collect();
    }

then in the main function:-

public static void Main(string[] args)
    {


        Timer t = new Timer(TimerCallback, null, 0, X * 1000);
        Console.ReadLine();
    }

This application only works on the first loop because it can only see the incremented value of X on the first loop of the Timer then remains constant without updating.

so the output is:

Value:1

what i want to do is use the Timer function's last parameter to multiply X's value (as it changes everytime the loop is over) with the milliseconds.

is this even possible?

Upvotes: 2

Views: 5582

Answers (2)

Gabriel Ioniță
Gabriel Ioniță

Reputation: 121

When you instantiate your Timer, what you are actually doing is to set both the dueDate and period to 0 (X is 0 at start time). The dueDate equals to 0 means that the timer starts immediately, and the period 0 means that there won't be any more repetitions. This is odd because in the documentation it says that you should specify System.Threading.Timeout.Infine to disable periodic signaling.

You can try something like this to change the time interval between the TimerCallback calls:

public static int X;
public static Timer timer;
public static int ReturnInt()
{
    X = X + 1;
    return X;
}

public static void TimerCallback(object o)
{
    var y = ReturnInt();
    Console.WriteLine("Value:" + y);
    timer.Change(y * 1000, 0);
    GC.Collect();
}

public static void Main(string[] args)
{
    timer = new Timer(TimerCallback, null, 0, 0);
    Console.ReadLine();
}

In Main you create a timer that runs immediately and, in the TimerCallback method you change the timers properties using the timer.Change(y * 1000, 0), and so the method will be called at y * 1000 milliseconds each time the value changes.

Upvotes: 3

Sean T
Sean T

Reputation: 2494

How about declare x outside the main body, pass it through as an aboject to the callback.

public Int x = 0;

public static void Main(string[] args)
{
    Timer t = new Timer(TimerCallback, x, 0, x * 1000);
    Console.ReadLine();
}

pass it in to the incremental method.

private int ReturnInt(int x)
{
    x = x + 1
    return x;
}

and in your callback you take it from the object you passed into it for the delegate?

private void TimerCallback(int x)
{
    var y = ReturnInt(x);
    Console.WriteLine("Value:" + y);
    GC.Collect();
}

You would need to set some condition when to stop this as x will get very large very quickly. This is just set to run indefinitley.

Upvotes: 0

Related Questions