Synchronizing Forms.Timer and Diagnostics.Stopwatch - c#

I have a function (say foo())that will be called from time to time with a variable interval. When it is called, it checks the time and takes an action accordingly.
I have done this in the following way:
A Forms.Timer object invokes the function when required
A Diagnostics.Stopwatch object is used within the function for the purpose of determining the time and deciding what to do.
However I have the following problem: when foo() is called by Timer's callback, the ElapsedMilliseconds value of stopwatch object is usually lower than expected. For example, timer is set to 1000 so after 1000 ms foo() is called, but within foo() body ElapsedMilliseconds return 900 therefore foo behaves as if the elapsed time was 900 (although it should take the action A because 1000 ms actually elapsed, it does not)
How can I synchronize timer and stopwatch in such case that ElapsedMilliseconds have a consistent value with timer?
EDIT: Some Code
Some sample code to explain what is my problem:
//foo is the function that is called by timer's callback
public void foo()
{
//Let's see what time it is:
long currentTime = stopwatch.ElapsedMilliseconds();
Item = getCurrentItem(currentTime);
Item.Draw();
}
//this is the callback of timer
private void timer1_Tick(object sender, EventArgs e)
{
//set the timer for next time
timer1.Interval = Intervals[periodIdx++];
foo();
}
This is supposed to draw something else each time when an interval is completed, however since ElapsedMilliseconds return an earlier value than timer claims, although the interval is over, next item isn't drawn

You get the big difference because you start the timer somewhere within the 1/64 second interval. You'll get better results with this:
private void StartTimers() {
int tick = Environment.TickCount;
while (Environment.TickCount == tick) Thread.Sleep(0);
timer1.Enabled = true;
stopwatch.Start();
}
Where the while() loop improves the odds that the timer gets started at the start of a 1/64 timer tick. Just improves, no guarantees. And you can't do anything about the Tick event firing late, it entirely depends on the responsiveness of your UI thread. It is however always late. Don't use this code, write your code so you don't care that these timers are not in sync. You may have to reduce the timer's Interval to accomplish that, it isn't clear from the question.

You aren't going to have much success with this approach. You're not starting each timer at the exact same time and you're not checking them at the exact same time (there some passage of time between the Timer firing it's event and your code querying the Stopwatch).
Pick a single timer and base everything off of it if you want things in sync. For example, if you want to go with the Forms.Timer, in your event handler for it just increment a counter variable - that will tell you how many times your handler has been called and, effectively, how much time the Forms.Timer says has passed. Here's an example (I'll leave it to you to handle the case of the timer ticking long enough that the counter exceeds long.MaxValue)
public void foo()
{
Item = getCurrentItem(totalElapsed);
Item.Draw();
}
long totalElapsed = 0;
private void timer1_Tick(object sender, EventArgs e)
{
totalElapsed += timer1.Interval;
//set the timer for next time
timer1.Interval = Intervals[periodIdx++];
foo();
}

Related

Execute a function ever 60 seconds

I want to execute a function every 60 seconds in C#. I could use the Timer class like so:
timer1 = new Timer();
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = 60 * 1000; // in miliseconds
timer1.Start();
Question is I have a long running process. Occasionally it make take several minutes. Is there a way to make the timer smart so if the function is already being executed then it should skip that cycle and come back 60 seconds later and if again it is in execution then again skip and come back 60 seconds later.
I would suggest you to have a class member variable bool variable with value false.
then in click event return if its true at the beginning.
and then set it to true, so that it will tell you that its currently in execution.
then write your logic.
and then once done finally set it to false again.
code will look like this.
private bool isRunning = false;
private void timer1_Tick(object sender, EventArgs e)
{
if (isRunning)
{
return;
}
isRunning = true;
try
{
... //Do whatever you want
}
finally
{
isRunning = false;
}
}
The modern and most clean way to do this is using Microsoft's new Period Timer:
var timer = new PeriodicTimer(TimeSpan.FromSeconds(n));
while (await timer.WaitForNextTickAsync())
{
//Business logic
}
If you need to abort such a ticker, you can pass a cancellation token to the WaitForNextTickAsync method.
Another advantage is this:
The PeriodicTimer behaves like an auto-reset event, in that multiple ticks are coalesced into a single tick if they occur between calls to WaitForNextTickAsync(CancellationToken). Similarly, a call to Dispose() will void any tick not yet consumed. WaitForNextTickAsync(CancellationToken) may only be used by one consumer at a time, and may be used concurrently with a single call to Dispose().
Source: https://learn.microsoft.com/en-us/dotnet/api/system.threading.periodictimer.waitfornexttickasync?source=recommendations&view=net-7.0#remarks
If you need more granularity (like "always at 10 am", use something like https://github.com/HangfireIO/Cronos
Use a timer, set it to 60 second
On Event:
try
Stop timer
Do logic
catch
What ever fail recovery
finally
Start the timer
Logic is run 60 seconds after last finish.
You can use a Stopwatch inside a loop: start the stopwatch, after 60 second call the function, reset the stopwatch, start the loop again.

Reduce an integer every second in c# [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I'm trying to figure out how to reduce an integer every second. Everything suggests things that are many, many lines long, and are explaining things in a generic, interchangeable way. So far I've set it up as...
public int timer = 180;
public Text timerCounterText;
// Use this for initialization
void Start ()
{
timerCounterText.text = "Time Left: " + timer.ToString();
}
Now I have no idea how to actually make the integer decrease by one each second, I don't want any suggestions of a potentially better way to do it unless there's no way to do it from what I have here.
I just want a simple, in as few lines as possible way to reduce my timer integer by 1 each second, as the way I have done this is the only way I understand how to do this so far.
Sorry if this is too much to ask, I just want a script I can understand, not just one that works best, as I'm just a student, not making a product.
I have worked a lot with timers in C# (a HELL of a lot - I used to develop software for a Sports Timing company).
There are a few ways of doing it. Some more accurate than others.
The simplest - which is the way you're looking at would be like so:
Set your total seconds in a private field:
private int _secondsRemaining = 180; // 3 minutes
Create a Timer stored in a private field:
private System.Timers.Timer _countdownTimer;
Create a StartTimer() method. Initialize the _countdownTimer, and create an Event Handler for when the timer ticks - this is what happens when it "reaches 0"/fires/whatever you want to call it:
public void StartTimer()
{
_countdownTimer = new System.Timers.Timer(1000); // 1000 is the number of milliseconds
// 1000ms = 1 second
// Set a handler for when the timer "ticks"
// The "Tick" event will be fired after 1 second (as we've set it)
// The timer will loop, though and keep firing until we stop it
// Or unless it is set to not automatically restart
_countdownTimer.Tick += OnTimer_Tick;
// Start the timer!
_countdownTimer.Start();
}
You will need to call StartTimer() from somewhere in your program, otherwise it won't ever start (obviously) - you can do this from the constructor or a button click etc.
Now, create an Event Handler for when the timer ticks. In this, decrement (take 1 from) the _secondsRemaining value; and then display it in your timerCounterText label:
// This is what gets fired when the timer "reaches 0"
private void OnTimer_Tick(object sender, ElapsedEventArgs e)
{
_secondsRemaining--; // the same as "_secondsRemaining = secondsRemaining -1"
timerCounterText.Text = string.Format("Time Remaining: {0} seconds",
_secondsRemaining);
}
This is a nice and easy way to make a countdown timer.
The drawback is, that the timer doesn't fire EXACTLY every second, so you may notice a little bit of drift.
Like I mentioned; depending on the accuracy you need, there are other ways I have used. It depends on what the timer's being used for.
WAIT! There's more!
What would also be useful (if you need it), is, when the _secondsRemaining reaches 0 to stop the timer.
Create a StopTimer() method:
private void StopTimer()
{
if (_countdownTimer != null)
{
_countdownTimer.Tick -= OnTimer_Tick;
_countdownTimer.Stop();
_countdownTimer.Dispose();
_countdownTimer = null;
}
}
You could also use this method when you want to stop the timer manually from a button click or whatever.
Notice the null check, and the code within it. The null check is just for damage limitation in case the _countdownTimer hasn't been initialized etc. and to stop your program bombing out if so.
The code within the if check unsubscribes from the Tick event, stops the timer (obviously), and then gets rid of the _countdownTimer - you don't need to; but you will need to unsubscribe & stop it...
If we called StartTimer() again and initialized the timer, we'd be adding another subscription to the Tick event - this would cause the OnTimer_Tick method to be called twice every time the _countdownTimer fires (and so on and so forth).
Now, in your OnTimer_Tick handler, where we decrement the value of _secondsRemaining - check after, if it is less or equal to 0:
private void OnTimer_Tick(object sender, ElapsedEventArgs e)
{
_secondsRemaining--; // decrement the _secondsRemaining as before
if (_secondsRemaining <= 0)
{
StopTimer(); // This will stop the timer when the _secondsRemaining
// reach 0 (or go below - it shouldn't)
// You can also add in other stuff to happen at 0
// such as "Ending the game", as you described
}
// Display the time remaining, still - as before
timerCounterText.Text = string.Format("Time Remaining: {0} seconds",
_secondsRemaining);
}
Where the check for _secondsRemaining <= 0 is, you could also add your own methods for other things to happen - such as Ending your game as you asked in your question :)
I won't go into any more detail; and I'll let you figure it out - but you could even add in ResetTimer() methods, so you could start the timer again.
I hope this helps - any questions or any other ways to do timers you need; just ask.
I would advise a separate thread doing a decrease in the integer. I would do this with a while loop
public event SecondHappenedEventHandler SecondHappened;
public delegate void SecondHappenedEventHandler(int second);
private int timer = 180;
Public Void Start()
{
timer = 180;
Thread th = New Thread(New ThreadStart(Monitor);
th.Start();
}
Private Void Monitor()
{
While (timer != 0)
{
timer--;
SecondHappened(timer);
Thread.Sleep(1000); //This is milliseconds
}
}
My C# is a little rusty since I have been doing VB more recently for work. Then Add a raiseevent in that class that passes back the integer to the the other class. So your other class would make an instance of this class and have an event that gets the second passed back and display it to the end user.
public Text timerCounterText;
private TimerClass timer;
// Use this for initialization
void Start ()
{
timer.Start
}
private void SecondHappened(int timerBack)
{
timerCounterText.text = "Time Left: " + timerBack.ToString();
}
You can use one of the few Timer classes in .NET in order to get your program do stuff in regular intervals. There's usually one type of timer class that is appropriate for a given situation depending on your app type(i.e. Windows, Console, Service...etc)
Since you are after a simple example, you can have a look at the System.Timers.Timer class:
Generates an event after a set interval, with an option to generate recurring events.
Example of it's usage in a console application (P.S. If you have Windows Forms apps, you probably don't want to use it in this way):
int _countDown = 180;
void Start()
{
var timer = new System.Timers.Timer(1000); // Duration in milliseconds
timer.Elapsed += async ( sender, e ) => await HandleTimer();
timer.Start();
}
void HandleTimer()
{
_countDown--;
Console.WriteLine("Time Left: {0}", _countDown);
}
If you work in WF (Windows Forms), I suggest using a Timer. Create a timer control, set it's interval to 1000 (milliseconds), and in your start function just enable it:
void Start ()
{
timer1.Enabled = true;
timerCounterText.text = "Time Left: " + timer.ToString();
}
Now, a double click on the timer should create a timer_tick event. Use it like that:
void timer_Tick(object sender, EventArgs e)
{
timerCounterText.text = "Time Left: " + (--timer).ToString();
}
Then it should reduce the timer by 1 every second. Of course you should check when it arrives to 0, and then set timer1.Enabled to false.
Using the Decrement Operator --
If you wanted to decrement it prior to the value being updated, you could use the decrement operator --:
void Start ()
{
// This will decrement the timer by 1
timer--;
// Output the value
timerCounterText.Text = "Time Left: " + timer.ToString();
}
You could also accomplish this same thing inline using prefix notation, which will update the value prior to using it :
void Start ()
{
// Decrement your count and output it
timerCounterText.Text = "Time Left: " + (--timer).ToString();
}
Cleaning Up Your Output
You can clean up your output a bit more by using the String.Format() method as well :
void Start ()
{
// Decrement your count and output it
timerCounterText.Text = String.Format("Time Left: {0}",--timer);
}
or if you are using C#, you can take advantage of String Interpolation :
void Start ()
{
// Decrement your count and output it
timerCounterText.Text = $"Time Left: {--timer}";
}
Making Your Timer Tick
Assuming that you are using a Timer class, you can set it's Tick event to be triggered as a certain interval. This is what you would use to actually decrement your value and output it to the user :
// Define a timer
Timer countDown = new Timer();
// Sets the timer interval to 1 seconds.
countDown.Interval = 1000;
// Call the tick event every second
countDown.Tick += new EventHandler(Tick);
// Start your timer
countDown.Start();
and your Tick event would look like this :
private static void Tick(Object myObject,EventArgs myEventArgs)
{
// Check if your timer has run out
if(countDown <= 0)
{
// Timer has run out, handle accordingly
countDown.Stop();
}
else
{
// Otherwise output and decrement
String.Format("Time Left: {0}",--timer);
}
}

c# looping method in WPF

I am sure this may have been answer somewhere but I have searched all over the web and cannot find an obvious solution?
private void button5_Click(object sender, RoutedEventArgs e)
{
if (stopwatch.IsRunning == false)
{
stopwatch.Start();
while (stopwatch.IsRunning == true)
{
label7.Content = stopwatch.Elapsed.ToString();
Thread.Sleep(1000);
}
}
}
label7 does not update and I am assuming its because the while loop never exits?
but I also tried this with no joy?
private void button5_Click(object sender, RoutedEventArgs e)
{
if (stopwatch.IsRunning == false)
{
stopwatch.Start();
}
label7.Content = stopwatch.Elapsed.ToString();
Thread.Sleep(1000);
button5_Click(sender, e);
}
You don't want to do a Thread.Sleep(1000) in there. That will make it so that the UI won't be able to update itself. Instead, use a timer and when the timer tick event fires, change the text in the label.
So for your example, when you define the stopwatch, define its interval and then add an event handler for the 'Tick' event. When it 'ticks' set the content of your label.
Use a DispatcherTimer so that you don't have to shift to the UI thread, as your timer will work within the UI thread for you.
Since you are creating a timer class, you should use the Timer Elapsed event. Update your UI in there.
MSDN Timer Elapsed Event Description
As has been said, sleeping your process thread will essentially freeze the application. Generally avoid it if you can unless you have a very specific reason to sleep a thread. 1 second is also an eternity for a computer, so your elapsed time increments should be relatively small. A user will notice 1 second, they will have a harder time notice increments of .1 s and less.

How to reset a timer in C#?

There are three Timer classes that I am aware of, System.Threading.Timer, System.Timers.Timer, and System.Windows.Forms.Timer, but none of these have a .Reset() function which would reset the current elapsed time to 0.
Is there a BCL class that has this functionality? Is there a non-hack way of doing it? (I thought perhaps changing the time limit on it might reset it) Thought on how hard it would be to reimplement a Timer class that had this functionality, or how to do it reliably with one of the BCL classes?
I always do ...
myTimer.Stop();
myTimer.Start();
... is that a hack? :)
Per comment, on Threading.Timer, it's the Change method ...
dueTime Type: System.Int32 The
amount of time to delay before the
invoking the callback method specified
when the Timer was constructed, in
milliseconds. Specify
Timeout.Infinite to prevent the
timer from restarting. Specify zero
(0) to restart the timer immediately.
All the timers have the equivalent of Start() and Stop() methods, except System.Threading.Timer.
So an extension method such as...
public static void Reset(this Timer timer)
{
timer.Stop();
timer.Start();
}
...is one way to go about it.
For System.Timers.Timer, according to MSDN documentation, http://msdn.microsoft.com/en-us/library/system.timers.timer.enabled.aspx:
If the interval is set after the Timer has started, the count is
reset. For example, if you set the interval to 5 seconds and then set
the Enabled property to true, the count starts at the time Enabled is
set. If you reset the interval to 10 seconds when count is 3 seconds,
the Elapsed event is raised for the first time 13 seconds after
Enabled was set to true.
So,
const double TIMEOUT = 5000; // milliseconds
aTimer = new System.Timers.Timer(TIMEOUT);
aTimer.Start(); // timer start running
:
:
aTimer.Interval = TIMEOUT; // restart the timer
You could write an extension method called Reset(), which
calls Stop()-Start() for Timers.Timer and Forms.Timer
calls Change for Threading.Timer
I just assigned a new value to the timer:
mytimer.Change(10000, 0); // reset to 10 seconds
It works fine for me.
at the top of the code define the timer: System.Threading.Timer myTimer;
if (!active)
myTimer = new Timer(new TimerCallback(TimerProc));
myTimer.Change(10000, 0);
active = true;
private void TimerProc(object state)
{
// The state object is the Timer object.
var t = (Timer)state;
t.Dispose();
Console.WriteLine("The timer callback executes.");
active = false;
// Action to do when timer is back to zero
}
For a Timer (System.Windows.Forms.Timer).
The .Stop, then .Start methods worked as a reset.
You can do timer.Interval = timer.Interval
I do the following.
Disposing the timer and initializing it again.
But this will erase any event you attached to this timer.
timer.Dispose();
timer = new System.Timers.Timer();
Other alternative way to reset the windows.timer is using the counter, as follows:
int timerCtr = 0;
Timer mTimer;
private void ResetTimer() => timerCtr = 0;
private void mTimer_Tick()
{
timerCtr++;
// Perform task
}
So if you intend to repeat every 1 second, you can set the timer interval at 100ms, and test the counter to 10 cycles.
This is suitable if the timer should wait for some processes those may be ended at the different time span.
i do this
//Restart the timer
queueTimer.Enabled = true;

Best Timer for using in a Windows service

Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
I need to create some windows service which will execute every N period of time.
The question is:
Which timer control should I use: System.Timers.Timer or System.Threading.Timer one? Does it influence on something?
I am asking because I heard many evidences to non correct work of System.Timers.Timer in windows services.
Thank you.
Both System.Timers.Timer and System.Threading.Timer will work for services.
The timers you want to avoid are System.Web.UI.Timer and System.Windows.Forms.Timer, which are respectively for ASP applications and WinForms. Using those will cause the service to load an additional assembly which is not really needed for the type of application you are building.
Use System.Timers.Timer like the following example (also, make sure that you use a class level variable to prevent garbage collection, as stated in Tim Robinson's answer):
using System;
using System.Timers;
public class Timer1
{
private static System.Timers.Timer aTimer;
public static void Main()
{
// Normally, the timer is declared at the class level,
// so that it stays in scope as long as it is needed.
// If the timer is declared in a long-running method,
// KeepAlive must be used to prevent the JIT compiler
// from allowing aggressive garbage collection to occur
// before the method ends. (See end of method.)
//System.Timers.Timer aTimer;
// Create a timer with a ten second interval.
aTimer = new System.Timers.Timer(10000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
// Set the Interval to 2 seconds (2000 milliseconds).
aTimer.Interval = 2000;
aTimer.Enabled = true;
Console.WriteLine("Press the Enter key to exit the program.");
Console.ReadLine();
// If the timer is declared in a long-running method, use
// KeepAlive to prevent garbage collection from occurring
// before the method ends.
//GC.KeepAlive(aTimer);
}
// Specify what you want to happen when the Elapsed event is
// raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
}
}
/* This code example produces output similar to the following:
Press the Enter key to exit the program.
The Elapsed event was raised at 5/20/2007 8:42:27 PM
The Elapsed event was raised at 5/20/2007 8:42:29 PM
The Elapsed event was raised at 5/20/2007 8:42:31 PM
...
*/
If you choose System.Threading.Timer, you can use as follows:
using System;
using System.Threading;
class TimerExample
{
static void Main()
{
AutoResetEvent autoEvent = new AutoResetEvent(false);
StatusChecker statusChecker = new StatusChecker(10);
// Create the delegate that invokes methods for the timer.
TimerCallback timerDelegate =
new TimerCallback(statusChecker.CheckStatus);
// Create a timer that signals the delegate to invoke
// CheckStatus after one second, and every 1/4 second
// thereafter.
Console.WriteLine("{0} Creating timer.\n",
DateTime.Now.ToString("h:mm:ss.fff"));
Timer stateTimer =
new Timer(timerDelegate, autoEvent, 1000, 250);
// When autoEvent signals, change the period to every
// 1/2 second.
autoEvent.WaitOne(5000, false);
stateTimer.Change(0, 500);
Console.WriteLine("\nChanging period.\n");
// When autoEvent signals the second time, dispose of
// the timer.
autoEvent.WaitOne(5000, false);
stateTimer.Dispose();
Console.WriteLine("\nDestroying timer.");
}
}
class StatusChecker
{
int invokeCount, maxCount;
public StatusChecker(int count)
{
invokeCount = 0;
maxCount = count;
}
// This method is called by the timer delegate.
public void CheckStatus(Object stateInfo)
{
AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;
Console.WriteLine("{0} Checking status {1,2}.",
DateTime.Now.ToString("h:mm:ss.fff"),
(++invokeCount).ToString());
if(invokeCount == maxCount)
{
// Reset the counter and signal Main.
invokeCount = 0;
autoEvent.Set();
}
}
}
Both examples comes from the MSDN pages.
Don't use a service for this. Create a normal application and create a scheduled task to run it.
This is the commonly held best practice. Jon Galloway agrees with me. Or maybe its the other way around. Either way, the fact is that it is not best practices to create a windows service to perform an intermittent task run off a timer.
"If you're writing a Windows Service that runs a timer, you should re-evaluate your solution."
–Jon Galloway, ASP.NET MVC community program manager, author, part time superhero
Either one should work OK. In fact, System.Threading.Timer uses System.Timers.Timer internally.
Having said that, it's easy to misuse System.Timers.Timer. If you don't store the Timer object in a variable somewhere, then it is liable to be garbage collected. If that happens, your timer will no longer fire. Call the Dispose method to stop the timer, or use the System.Threading.Timer class, which is a slightly nicer wrapper.
What problems have you seen so far?
I agree with previous comment that might be best to consider a different approach. My suggest would be write a console application and use the windows scheduler:
This will:
Reduce plumbing code that replicates scheduler behaviour
Provide greater flexibility in terms
of scheduling behaviour (e.g. only
run on weekends) with all scheduling logic abstracted from application code
Utilise the command line arguments
for parameters without having to
setup configuration values in config
files etc
Far easier to debug/test during development
Allow a support user to execute by invoking
the console application directly
(e.g. useful during support
situations)
As already stated both System.Threading.Timer and System.Timers.Timer will work. The big difference between the two is that System.Threading.Timer is a wrapper arround the other one.
System.Threading.Timer will have more exception handling while
System.Timers.Timer will swallow all the exceptions.
This gave me big problems in the past so I would always use 'System.Threading.Timer' and still handle your exceptions very well.
I know this thread is a little old but it came in handy for a specific scenario I had and I thought it worth while to note that there is another reason why System.Threading.Timer might be a good approach.
When you have to periodically execute a Job that might take a long time and you want to ensure that the entire waiting period is used between jobs or if you don't want the job to run again before the previous job has finished in the case where the job takes longer than the timer period.
You could use the following:
using System;
using System.ServiceProcess;
using System.Threading;
public partial class TimerExampleService : ServiceBase
{
private AutoResetEvent AutoEventInstance { get; set; }
private StatusChecker StatusCheckerInstance { get; set; }
private Timer StateTimer { get; set; }
public int TimerInterval { get; set; }
public CaseIndexingService()
{
InitializeComponent();
TimerInterval = 300000;
}
protected override void OnStart(string[] args)
{
AutoEventInstance = new AutoResetEvent(false);
StatusCheckerInstance = new StatusChecker();
// Create the delegate that invokes methods for the timer.
TimerCallback timerDelegate =
new TimerCallback(StatusCheckerInstance.CheckStatus);
// Create a timer that signals the delegate to invoke
// 1.CheckStatus immediately,
// 2.Wait until the job is finished,
// 3.then wait 5 minutes before executing again.
// 4.Repeat from point 2.
Console.WriteLine("{0} Creating timer.\n",
DateTime.Now.ToString("h:mm:ss.fff"));
//Start Immediately but don't run again.
StateTimer = new Timer(timerDelegate, AutoEventInstance, 0, Timeout.Infinite);
while (StateTimer != null)
{
//Wait until the job is done
AutoEventInstance.WaitOne();
//Wait for 5 minutes before starting the job again.
StateTimer.Change(TimerInterval, Timeout.Infinite);
}
//If the Job somehow takes longer than 5 minutes to complete then it wont matter because we will always wait another 5 minutes before running again.
}
protected override void OnStop()
{
StateTimer.Dispose();
}
}
class StatusChecker
{
public StatusChecker()
{
}
// This method is called by the timer delegate.
public void CheckStatus(Object stateInfo)
{
AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;
Console.WriteLine("{0} Start Checking status.",
DateTime.Now.ToString("h:mm:ss.fff"));
//This job takes time to run. For example purposes, I put a delay in here.
int milliseconds = 5000;
Thread.Sleep(milliseconds);
//Job is now done running and the timer can now be reset to wait for the next interval
Console.WriteLine("{0} Done Checking status.",
DateTime.Now.ToString("h:mm:ss.fff"));
autoEvent.Set();
}
}

Categories

Resources