Question About Timers And Variable Intervals - c#

The point of this timer is to execute some code whenever it's midnight.
So basically, the first interval will be between Now and midnight and all intervals following that will be 24hours.
Now that's all well and good, but I was wondering how this timer business works. Is the MyTimer.Interval recalculated each time the timer resets?
System.Timers.Timer MyTimer = new System.Timers.Timer();
MyTimer.Elapsed += new ElapsedEventHandler(TriggeredMethod);
MyTimer.Interval = [pseudocode]Time between now and midnight[/pseudocode];
MyTimer.Start();
EDIT:
I'm having trouble setting the Interval inside of my TriggerMethod. Where/how should I initiate the Timer so I don't get any context errors?
private void Form1_Load(object sender, EventArgs e)
{
System.Timers.Timer MyTimer = new System.Timers.Timer();
MyTimer.Elapsed += new ElapsedEventHandler(TriggeredMethod);
MyTimer.Start();
}
private void TriggerMethod(object source, ElapsedEventArgs e)
{
MyTimer.Interval = [pseudocode]Time between now and midnight[/pseudocode];
}

The Interval property is the number of milliseconds between timer invocations.
To run the timer at midnight, you would need to change Interval in each Elapsed event to (int)(DateTime.Today.AddDays(1) - DateTime.Now).TotalMilliseconds.
To access the timer inside the Elapsed handler, you'll need to store the timer in a field in your class, like this:
System.Timers.Timer MyTimer
private void Form1_Load(object sender, EventArgs e)
{
MyTimer = new System.Timers.Timer();
//...
}
Note, by the way, that System.Timers.Timer will not fire on the UI thread.
Therefore, you cannot manipulate the form inside the Elapsed handler.
If you need to manipulate the form, you can either switch to System.Windows.Forms.Timer (which is less accurate) or call BeginInvoke.

after the first run, you would have to update the interval, subtracting the current time from midnight the following day and assigning to the interval; I do this for one of my batch processes, and it works well.
HTH.

Make your timer fire once per hour, and then only do the actual work at midnight. And I also recommend using BeginInvoke to move the actual UI interaction onto the GUI thread.

Related

C# EvenHandler only updates once

I'm trying to get more familiar with eventhanlders, but my current even only updates once, I want it to update until I close the application.
This is my code:
private static event EventHandler Updater;
Updater += Program_updater;
Updater.Invoke(null, EventArgs.Empty);
Application.Run();
private static void Program_updater(object sender, EventArgs e)
{
KeyUtils.Update();
Framework.Update();
}
But like I said, it will only update once, I want it to update until I close my application. I know I can just do a While(true) but I rather not.
I think you want a Timer here:
Timer aTimer = new System.Timers.Timer(2000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += Program_updater;
// Have the timer fire repeated events (true is the default)
aTimer.AutoReset = true;
// Start the timer
aTimer.Enabled = true;
Specify callback:
private void Program_updater(Object source, System.Timers.ElapsedEventArgs e)
{
KeyUtils.Update();
Framework.Update();
}
Now every 2 seconds (or specify any other interval) callback OnTimedEvent will be called.
It is absolutely normal that your event is fired only once because the application starts only once.
What you acctualy need is to set up a timer and do some work on its tick.
Please have a look on example in answer for that question Simple example of the use of System. Timers. Timer in C#
Well it only updates once since you only invoke it once (I don't really get the context where your code runs since you both declare a static variable and invokes it on the same scope which is impossible).
If you want something to occur periodically you should use Timer, or in some cases AutoResetEvent/ManualResetEvent.
EventHandlers should be used only when you work as event driven which mean you want your handler to invoke When something happens
Here an example for [System.Timers.Timer][2] with your handler:
//Invoke every 5 seconds.
Timer timer = new Timer(5000);
//Add your handler to the timer invocation list.
timer.Elapsed += Program_updater;
//Start the timer.
timer.Start();
Also you need Program_update's signature to look like that:
private void Program_updater(object source, ElapsedEventArgs e)

Is it possible to change Timer Tick in the middle of running

I have application that execute some task via Timer every new minutes and i want to add the option to make this task changeable using user input in the middle of application running.
if for example my Timer.Tick is set to 1 minute and changed into 1 hour, Timer.Tick property will update ir i need to restart my application ?
I just ran this in LINQPad and it 'ticks' every second after I change the interval, meaning it looks like it respects your change to the interval property immediately.
void Main()
{
var timer = new System.Windows.Forms.Timer();
timer.Tick += Timer_Tick;
timer.Interval = 50000;
timer.Start();
System.Threading.Thread.Sleep(1000);
timer.Interval = 1000;
}
private void Timer_Tick(object sender, EventArgs e)
{
Console.WriteLine("Tick");
}
I'm assuming you are using System.Windows.Forms.Timer based on you referencing the Tick event. I also ran the same test using System.Threading.Timer and saw the same results.

Check if timer elapsed in thread

I have a while loop running in my .NET backgroundworker. I would like to end the loop when Timers.Timer reaches 0.
Problem is that since I'm working in another thread (backgroundworker), my timer has to be instantiated in that same thread. So I can't set any private boolean timer_Elapsed. Nether do I know how to give reference of boolean thro event.
Code Example:
private bool timer_Elapsed = false;
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
System.Timers.Timer timer = new System.Timers.Timer();
Set_Timer(timer);
timer.Start();
while(timer_Elapsed) //Has to be a boolean that indicates if timer elapsed
{
this.Do_Proces();
}
}
private void Set_Timer(System.Timers.Timer timer)
{
timer.Interval = 200;
timer.Elapsed += new ElapsedEventHandler(timer_ElapsedEvent);
}
private void timer_ElapsedEvent(object source, ElapsedEventArgs e)
{
timer_Elapsed = true; //I can't set my private boolean since it got instantiated in another thread
}
Particular questions in code. I'm new with this kind of stuff.
Any suggestions? Thanks in advance
EDIT: To clarify, I want the Do_Proces() to run for 200 milliseconds, when that time passed, I want it to stop. When it stops after 200 millisec, I want to and update GUI with data generated in backgroundWorker. Then check if user wants the proces to stop, if not, I want it to run again.. I use the timer because the thread will have to get restarted to much, this will have effect on the main thread as well, effecting the user experience badly.
Is the timer serving any other purpose other than listed here? If not, you may just want to record the current time at the beginning of your BackgroundWorker method, and change the condition on the while loop to check if the required amount of time has elapsed.
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
TimeSpan timeout = TimeSpan.FromMinutes(5);
DateTime start_time = DateTime.Now;
while(DateTime.Now - start_time < timeout)
{
this.Do_Proces();
}
}

What is the best way to implement a "timer"? [duplicate]

This question already has answers here:
How do you add a timer to a C# console application
(12 answers)
Closed 3 years ago.
What is the best way to implement a timer? A code sample would be great! For this question, "best" is defined as most reliable (least number of misfires) and precise. If I specify an interval of 15 seconds, I want the target method invoked every 15 seconds, not every 10 - 20 seconds. On the other hand, I don't need nanosecond accuracy. In this example, it would be acceptable for the method to fire every 14.51 - 15.49 seconds.
Use the Timer class.
public static void Main()
{
System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 5000;
aTimer.Enabled = true;
Console.WriteLine("Press \'q\' to quit the sample.");
while(Console.Read() != 'q');
}
// Specify what you want to happen when the Elapsed event is raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Console.WriteLine("Hello World!");
}
The Elapsed event will be raised every X amount of milliseconds, specified by the Interval property on the Timer object. It will call the Event Handler method you specify. In the example above, it is OnTimedEvent.
By using System.Windows.Forms.Timer class you can achieve what you need.
System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
t.Interval = 15000; // specify interval time as you want
t.Tick += new EventHandler(timer_Tick);
t.Start();
void timer_Tick(object sender, EventArgs e)
{
//Call method
}
By using stop() method you can stop timer.
t.Stop();
It's not clear what type of application you're going to develop (desktop, web, console...)
The general answer, if you're developing Windows.Forms application, is use of
System.Windows.Forms.Timer class. The benefit of this is that it runs on UI thread, so it's simple just define it, subscribe to its Tick event and run your code on every 15 second.
If you do something else then windows forms (it's not clear from the question), you can choose System.Timers.Timer, but this one runs on other thread, so if you are going to act on some UI elements from the its Elapsed event, you have to manage it with "invoking" access.
Reference ServiceBase to your class and put the below code in the OnStartevent:
Constants.TimeIntervalValue = 1 (hour)..Ideally you should set this value in config file.
StartSendingMails = function name you want to run in the application.
protected override void OnStart(string[] args)
{
// It tells in what interval the service will run each time.
Int32 timeInterval = Int32.Parse(Constants.TimeIntervalValue) * 60 * 60 * 1000;
base.OnStart(args);
TimerCallback timerDelegate = new TimerCallback(StartSendingMails);
serviceTimer = new Timer(timerDelegate, null, 0, Convert.ToInt32(timeInterval));
}

How to stop a timer after it is done running?

I have a Console App and in the main method, I have code like this:
Timer time = new Timer(seconds * 1000); //to milliseconds
time.Enabled = true;
time.Elapsed += new ElapsedEventHandler(time_Elapsed);
I only want the timer to run once so my idea is that I should stop the timer in the time_Elapsed method. However, since my timer exists in Main(), I can't access it.
You have access to the Timer inside of the timer_Elapsed method:
public void timer_Elapsed(object sender, ElapsedEventArgs e)
{
Timer timer = (Timer)sender; // Get the timer that fired the event
timer.Stop(); // Stop the timer that fired the event
}
The above method will stop whatever Timer fired the Event (in case you have multiple Timers using the same handler and you want each Timer to have the same behavior).
You could also set the behavior when you instantiate the Timer:
var timer = new Timer();
timer.AutoReset = false; // Don't reset the timer after the first fire
A little example app:
static void Main(string[] args)
{
int seconds = 2;
Timer time = new Timer(seconds * 1000); //to milliseconds
time.Enabled = true;
time.Elapsed += new ElapsedEventHandler(MyHandler);
time.Start();
Console.ReadKey();
}
private static void MyHandler(object e, ElapsedEventArgs args)
{
var timer = (Timer) e;
timer.Stop();
}
I assume that you're using System.Timers.Timer rather than System.Windows.Forms.Timer?
You have two options.
First, as probably the best, is to set the AutoReset property to false. This should do exactly what you want.
time.AutoReset = false;
The other option is to call Stop in the event handler.
You may also use the System.Threading.Timer. Its constructor takes two time-related parameters:
The delay before the first "tick" (due time)
The period
Set the period to Timeout.Infinite to prevent from firing again.

Categories