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 8 years ago.
Improve this question
I'm trying to make a program whereby it does something every x minutes. I have been experimenting with the Stopwatch function but it don't seem to run the code I want when the time is up.
Here's my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Threading;
namespace Testing
{
class Program
{
static void Main(string[] args)
{
Stopwatch testing = new Stopwatch();
testing.Start();
Thread.Sleep(6001);
TimeSpan ts = testing.Elapsed;
int timer = Convert.ToInt32(String.Format("{0}", ts.Seconds));
Console.Write(timer);
while (testing.Elapsed < TimeSpan.FromMinutes(8))
{
timer = Convert.ToInt32(String.Format("{0}", ts.Seconds));
if (timer % 60 == 0)
{
//run x code every 1 minutes
Console.WriteLine("1 min" + timer);
}
timer = Convert.ToInt32(String.Format("{0}", ts.Seconds));
if (timer % 120 == 0)
{
//run x code every 2 minutes
Console.WriteLine("2 min" + timer);
}
}
testing.Stop();
}
}
}
Stopwatch is a high-performance timer (usually with 100ns resolution) - it is entirely inappropriate for what you're trying to do. Stopwatch is used to measure time by taking snapshots of a system counter and then calculating the difference.
Since most of a scheduler's job is to wait until a job needs to be done, implementing a scheduler with a tight loop is extremely inefficient - the system is using CPU resources to decide to not do anything for most of the time.
To properly implement a scheduler (if that's what you're trying to do), look into using ManualResetEvent with a timeout option.
Using an event puts your current thread to sleep (so it's not using system resources while it's doing nothing) and when the timeout expires, the event is triggered and the code can call the function that you're trying to schedule.
If you want nothing else than a simple timer that tells you when an interval elapsed, use System.Timers.Timer instead: this makes it much simpler to schedule a callback (the Elapsed event is called when the timer expires) and you don't have to run a loop during the wait.
Edit:
If you simply want to call a callback function periodically, a simple timer is easier to hook up than an event. Here's a code sample using System.Timer (not my code, I copy & pasted this from MSDN, linked above):
private static Timer m_oTimer;
public static void Main ()
{
m_oTimer = new System.Timers.Timer ( 2 * 1000 * 60 ); // 2 minutes
m_oTimer.Elapsed += OnTimedEvent; // Timer callback
m_oTimer.Enabled = true; // Start timer
// Wait here (you can do other processing here, too)
Console.WriteLine ( "Press the Enter key to exit the program... " );
Console.ReadLine ();
Console.WriteLine ( "Terminating the application..." );
}
private static void OnTimedEvent ( Object source, ElapsedEventArgs e )
{
// This is called on a separate thread; do periodic processing here
Console.WriteLine ( "The Elapsed event was raised at {0}", e.SignalTime );
}
As suggested by xxbbcc, here's an implementation using ManualResetEvent.WaitOne() with a TimeOut:
static void Main(string[] args)
{
int TimeOut = (int)TimeSpan.FromMinutes(2).TotalMilliseconds;
System.Threading.ManualResetEvent mreDuration = new System.Threading.ManualResetEvent(false);
Task.Run(() => {
System.Threading.Thread.Sleep((int)TimeSpan.FromMinutes(30).TotalMilliseconds);
mreDuration.Set();
});
while(!mreDuration.WaitOne(TimeOut))
{
Console.WriteLine("Two Minutes...");
}
Console.WriteLine("Thirty Mintues!");
Console.ReadLine();
}
You should use Timer. If you want timer to stop running after, let's say, 'y' minutes, then you just store the start time in a variable and write the Timer.Stop() function so that it get executed after 'y' minutes (hint: write it in timer_tick event). Time period of the timer should be HCF of all x's and y. Remember to set time period in miliseconds.
Related
I have this if condition where I need to do some stuff if the difference is 15 min or so
if (DateTime.UtcNow - x.Timestamp == TimeSpan.FromMinutes(15))
{
//Do something
}
The above condition never satisfies when I check with == but when I do >= it gets into the condition but that's not what I need, I want 15 min or so difference.
Can someone explain this behavior?
Sample Data:
x = 2/17/2020 8:45:17 PM
//I cannot comment on the above answer i dont have enough Rep
I think a better solution for a time trigger to do something would be like so:
static System.Timers.Timer _t = new System.Timers.Timer();
void Init()
{
//Start a timer trigger every 300000 milliseconds = 5 minutes
_t.Interval = 300000;
_t.Elapsed += fiveMinutesElapsed;
_t.Enabled = true;
}
public void fiveMinutesElapsed()
{
t.Enabled = false;
//Do Something
t.Enabled = true;
}
Can someone explain this behavior?
Yes: It is very unlikely that the elapsed time calculated from DateTime.Now is exactly equal to your specified TimeSpan.
From your comments, it seems that you want to periodically check if it's time to do something. One easy way to do this is to use a Stopwatch to keep track of the amount of time that has elapsed since the last time you did the thing:
using System;
using System.Diagnostics;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
static void Main()
{
throttleTimer.Start();
// This loop simulates your periodic check to see if the action
// needs to be performed:
while (true)
{
doActionIfTimeElapsed(TimeSpan.FromSeconds(5));
Thread.Sleep(1000); // Simulate checking every 1 second or so.
}
}
static Stopwatch throttleTimer = new Stopwatch();
static void doActionIfTimeElapsed(TimeSpan period)
{
if (throttleTimer.Elapsed <= period)
return;
doAction();
throttleTimer.Restart();
}
static void doAction()
{
Console.WriteLine("Doing the action.");
}
}
}
This sample program will perform doAction() whenever you call doActionIfTimeElapsed() and more than 5 seconds has elapsed since the last time it called doAction().
Alternatively, if you want to perform an action after every N seconds without having to call a method to periodically check if the action should be performed, then you can use a System.Threading.Timer instead.
Option 1:
If x.Timestamp is something you can reset (not a server-/client-side readonly value), then use >= (or > as = is less likely to ever happen) and reset x.Timestamp to the current time. Also, check this answer for determining relative time.
Option 2:
If you just want to raise a function in every 15 minutes, you have the answer here.
Note that 3 different timers exist, if you will need one that operate within seconds or milliseconds, you may want to avoid overlapping: which is (only?) possible with System.Timers.Timer via its Enabled property.
Option 3:
If you want to raise a function inside a while loop in every 15 minutes, I propose to use a StopWatch.
var watch = new StopWatch();
watch.Start();
while(...)
{
if (watch.Elapsed > TimeSpan.FromMinutes(15))
{
// do your stuff
watch.Restart();
}
}
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);
}
}
I know this question has been asked quite a few times on SO, but none of them have been able to fix my problem. I want to call a function every 10 seconds using threads.
I have a function that does frame processing. I want to be able to grab a frame after every 10 seconds and then process it. My research showed that it would be best to use threads for that purpose, and, as I need to perform it after a specific period of time, I would also require a timer control.
I am not able to figure out how can use threading and timers together. Moreover, I have tried using a BackgroundWorker control which, while processing, hangs up my app badly. I have also tried using a timer control and tried calling the function every 10 seconds, but in that case, if the process exceeds 10 seconds that might cause some problems.
Any examples or source code that could show me how to call a function every 10 seconds using threading will be really appreciated.
You don't necessarily need threads. You can use await/async:
public async Task DoSomethingEveryTenSeconds()
{
while (true)
{
var delayTask = Task.Delay(10000);
DoSomething();
await delayTask; // wait until at least 10s elapsed since delayTask created
}
}
In this example, the returned task will never finish; to fix that you need to use some other condition instead of true.
In an application with a GUI, this will execute DoSomething on the UI thread via the message loop, like any other event (like a button click handler). If there is no GUI, it will run on a thread pool thread.
Use System.Windows.Forms.Timer
private Timer timer1;
public void InitTimer()
{
timer1 = new Timer();
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = 10000; // in miliseconds
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
yourfunctionhere();
}
In a Windows Forms application, add a timer from Visual Studio's ToolBox, double-click it under the Designer view, and put the functionality that you want to be executed every X seconds in the function that appears. Be sure to enable the Timer in the properties view; there you can also change your interval (in milliseconds).
You can use this code if you want to run code for 10 second then stop it
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Timers;
namespace Tdo
{
class Program
{
public static bool k=true;
static void Main(string[] args)
{
Timer q = new Timer(10000);
q.Elapsed += Q_Elapsed;
q.Start();
while(k)
{
Console.WriteLine(DateTime.Now);
}
Console.ReadKey();
}
private static void Q_Elapsed(object sender, ElapsedEventArgs e)
{
StopTheCode(ref k);
}
public static void StopTheCode(ref bool flag)
{
flag= false;
}
}
}
Here is simply write the Date time of now for 10 second and when timer elapsed it set the flag = false and the while stop but be aware those 10 second will depend on your device GHz mean number of execution of the instruction per second will vary
I'm trying to write a service in c# that should be run on a given interval (a timeout) from a given date. If the date is in the future the service should wait to start until the date time is reached.
Example:
If I set a timeout to be 1 hour from 21:00:00 I want the program to run every hour
If I set a timeout to be 1 hour from 3999.01.01 21:00:00 I want the program to until date and from then run each hour
I have sort of achieved that with the following code, but it has some problems!
When I install the service (with installutil) the service is marked as starting because of the 'Thread.Sleep()'. This service appears to be hanging and is "installing" until started.
The code inside 'ServiceTimer_Tick()' might take longer than the expected timeout. How can I prevent the timer stack from increasing if that happens?
Alternatives I've thought of :
include using the 'timeout.Interval' first time and then resetting it subsequent calls, but it doesn't feel right.
I've also considered ditching the entire service idea and compile it as a executable and set up a scheduled tasks.
Shortened example:
public Service()
{
_timeout = new TimeSpan(0,1,0,0);
_timer = new System.Timers.Timer();
_timer.Interval = _timeout.TotalMilliseconds;
_timer.Elapsed += new ElapsedEventHandler(ServiceTimer_Tick);
}
private void ServiceTimer_Tick(object sender, System.Timers.ElapsedEventArgs e)
{
lock (_obj)
{
// Stuff that could take a lot of time
}
}
public static void Main()
{
Run(new Service());
}
protected override void OnStart(string[] args)
{
long current = DateTime.Now.Ticks;
long start = new DateTime(2010,9,15,21,0,0).Ticks;
long timeout = _timeout.Ticks;
long sleep;
if (current > start)
sleep = timeout - ((current % timeout)) + (start % timeout);
else
sleep = start - current;
Thread.Sleep(new TimeSpan(sleep));
_timer.AutoReset = true;
_timer.Enabled = true;
_timer.Start();
}
This is easier with a System.Threading.Timer. You can tell it how long to wait before the first tick, and then how often to tick after that.
So, if you wanted to wait 2 days before starting, and then do something once per hour, you'd write:
Timer MyTimer = new Timer(TimerCallback, null, TimeSpan.FromHours(48), TimeSpan.FromHours(1));
That said, if this is something that only has to run once per hour, then it sounds like what you really want is an executable that you then schedule with Windows Task Scheduler.
You can use a System.Threading.Timer. It supports both a dueTime and a period which is just what you need.
you have to move the timer logic to a separate thread that you spawn from your OnStart routine. Then your logic cannot interfere with the SCM and the service will start normally.
Edit: Just to elaborate - for this task I don't think timers work very well, since you are not taking clock corrections into account which could lead to a skew (or even be incorrect if the user manually changes the clock time). That's why comparing to the clock time in small intervals is imo preferred.
The Run routine of that thread could look like this:
public void run()
{
while (processing)
{
//initiate action on every full hour
if (DateTime.Now.Second == 0 && DateTime.Now.Minute == 0)
{
//Do something here
DoSomething();
//Make sure we sleep long enough that datetime.now.second > 0
Thread.Sleep(1000);
}
Thread.Sleep(100);
}
}
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();
}
}