C# and how to use "System.Timers" - c#

I recently started to use C# and I wanted to use timers.
I read Windows help about how to declare and define a Timer.
What I don't understand is why I need the Console.ReadLine(); line to start the timer.
(Link to the example)
// Firstly, create a timer object for 5 seconds interval
timer = new System.Timers.Timer();
timer.Interval = 5000;
// Set elapsed event for the timer. This occurs when the interval elapses −
timer.Elapsed += OnTimedEvent;
timer.AutoReset = false;
// Now start the timer.
timer.Enabled = true;
Console.ReadLine(); // <------- !!!
What I want to do but I don't achieve is to start the timer as soon as it is declared. I dont want to write Console.ReadLine(); because I may not need a console.
Example: If i develop a timer class and I call it from an other class, how can I check the timer has been completed?
Thank you in advance.

You need to set Timer, than wait for time is elapsed which executes the OnTimedEvent, that is how you can check if it already elapsed.
// Create a timer with a two second interval.
timer = new System.Timers.Timer(2000);
// Hook up the Elapsed event for the timer.
timer.Elapsed += OnTimedEvent;
timer.AutoReset = true;
timer.Enabled = true;
The OnTimedEvent should look like this:
private static void OnTimedEvent(Object source, ElapsedEventArgs e)
{
Console.WriteLine("The Elapsed event was raised at {0:HH:mm:ss.fff}",
e.SignalTime);
}
If you need to Stop the timer you should call:
timer.Stop();
timer.Dispose();
You need Console.ReadLine(); just for not exiting the main method and the whole program. If you're developing something else like MVC or WPF, you don't need it.

Related

.Net: how to wait until System.Timers.Timer stops

I have a System.Timers.Timer instance created in the main thread. Now I call timer.Stop() to try to terminate that time and want to wait until the timer is really terminated. How could I do that?
Is there any similar method like System.Threading.Thread.Join()?
Here are some codes
//the main thread:
var aTimer = New Timer();
aTimer.Elapsed += SomeTimerTask;
aTimer.AutoReset = True;
aTimer.Start();
//some other logic...
//stop that timer:
aTimer.Stop();
//now I need to wait until that timer is really stopped,
//but I cannot touch the method SomeTimerTask().
//so I need something like System.Threading.Thread.Join()...
You could make use of a ResetEvents which are wait handles which can block a thread until you set the state to signaled:
class TimerAndWait
{
private ManualResetEvent resetEvent = new ManualResetEvent(false);
public void DoWork()
{
var aTimer = new System.Timers.Timer(5000);
aTimer.Elapsed += SomeTimerTask;
aTimer.Elapsed += ATimer_Elapsed;
aTimer.AutoReset = true;
aTimer.Start();
// Do something else
resetEvent.WaitOne(); // This blocks the thread until resetEvent is set
resetEvent.Close();
aTimer.Stop();
}
private void ATimer_Elapsed(object sender, ElapsedEventArgs e)
{
resetEvent.Set();
}
}
If you want a async/task-based solution you have to use the ThreadPool.RegisterWaitForSingleObject method
The Timer does not fire up the Elapsed when you call stop as you can read in the docs of the Stop()-Method:
Stops raising the Elapsed event by setting Enabled to false.
The Elapsed-Event is only triggered when the Timers Enabled-Property is set to true and the given Interval (which you have to set) is elapsed (this can happen multiple times).
So if you stop your Timer before the Interval is elapsed, you might have to trigger your code in some other way.

Timer inaccurate

I am trying to implement a delay of 10 seconds before calling a a method. However, the method is being called in just one second.
private void closeDoors(Floor floor)
{
Timer timer = new Timer();
timer.Interval = 10000;
timer.Tick += delegate
{
DoorManager(floor, Operation.CLOSE, null);
};
timer.Start();
}
Where am I going wrong?
Thank you for your assistant.
Your problem may occur because of not stopping the Timer after finishing its job. The following modified code should work (as long as I've experienced with Timer):
private void closeDoors(Floor floor) {
Timer timer = new Timer();
timer.Interval = 10000;
timer.Tick += (s,e) => {
DoorManager(floor, Operation.CLOSE, null);
((Timer)s).Stop();
};
timer.Start();
}
I manage to fix it by incrementing the timer Interval as the time delay was being utilised by a process invoked by another method call insideDoorManager().

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

Fire timer_elapsed immediately from OnStart in windows service

I'm using a System.Timers.Timer and I've got code like the following in my OnStart method in a c# windows service.
timer = new Timer();
timer.Elapsed += timer_Elapsed;
timer.Enabled = true;
timer.Interval = 3600000;
timer.Start();
This causes the code in timer_Elapsed to be executed every hour starting from an hour after I start the service. Is there any way to get it to execute at the point at which I start the service and then every hour subsequently?
The method called by timer_Elapsed takes too long to run to call it directly from OnStart.
Just start a threadpool thread to call the worker function, just like Timer does. Like this:
timer.Elapsed += timer_Elapsed;
ThreadPool.QueueUserWorkItem((_) => DoWork());
...
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
DoWork();
}
void DoWork() {
// etc...
}
Use AutoReset Property of System.Timers.Timer and set it value to "true".
No need to use timer.Start() because it does the same job as timer.Enabled = true;
timer = new Timer();
timer.Elapsed += timer_Elapsed;
timer.Enabled = true;
timer.Interval = 3600000;
timer.AutoReset = true;
AutoReset = true will set a value indicating that the Timer should raise the Elapsed event each time when the specified interval elapses.
If you want your Timer to be fired immediately then you could simply just initialize the Timer object without a specified interval (it will default to 100ms which is almost immediately :P), then set the interval within the called function to whatever you like. Here is an example of what I use in my Windows Service:
private static Timer _timer;
protected override void OnStart(string[] args)
{
_timer = new Timer(); //This will set the default interval
_timer.AutoReset = false;
_timer.Elapsed = OnTimer;
_timer.Start();
}
private void OnTimer(object sender, ElapsedEventArgs args)
{
//Do some work here
_timer.Stop();
_timer.Interval = 3600000; //Set your new interval here
_timer.Start();
}
Use System.Threading.Timer class instead of System.Timers.Timer as this type is just a wrapper for Threading Timer.
It also suits your requirement.
System.Threading.Timer timer =
new System.Threading.Timer(this.DoWork, this, 0, 36000);
Here are the details.

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