I am running a windows service and using a loop and Thread.Sleep to repeat a task, would it be better to use a timer method?
If yes a code example would be great
I am currently using this code to repeat
int curMinute;
int lastMinute = DateTime.Now.AddMinutes(-1).Minute;
while (condition)
{
curMinute = DateTime.Now.Minute;
if (lastMinute < curMinute) {
// do your once-per-minute code here
lastMinute = curMinute;
}
Thread.Sleep(50000); // sleeps for 50 seconds
if (error condition that would break you out of this) {
break; // leaves looping structure
}
}
A timer is a better idea, IMO. That way, if your service is asked to stop, it can respond to that very quickly, and just not call the timer tick handler again... if you're sleeping, the service manager will either have to wait 50 seconds or kill your thread, neither of which is terribly nice.
class Program
{
static void Main(string[] args)
{
Timer timer = new Timer(new TimerCallback(TimeCallBack),null,1000,50000);
Console.Read();
timer.Dispose();
}
public static void TimeCallBack(object o)
{
curMinute = DateTime.Now.Minute;
if (lastMinute < curMinute) {
// do your once-per-minute code here
lastMinute = curMinute;
}
}
The code could resemble something like the one above
It's important to understand that your code will sleep for 50 seconds between ending one loop, and starting the next...
A timer will call your loop every 50 seconds, which isn't exactly the same.
They're both valid, but a timer is probably what you're looking for here.
Beware that calling Sleep() will freeze the service, so if the service is requested to stop, it won't react for the duration of the Sleep() call.
Yes, using a Timer will free up a Thread that is currently spending most of its time sleeping. A Timer will also more accurately fire every minute so you probably won't need to keep track of lastMinute anymore.
Not quite answering the question, but rather than having
if (error condition that would break you out of this) {
break; // leaves looping structure
}
You should probably have
while(condition && !error_condition)
Also, I'd go with a Timer.
I have used both timers and Thread.Sleep(x), or either, depending on the situation.
If I have a short piece of code that needs to run repeadedly, I probably use a timer.
If I have a piece of code that might take longer to run than the delay timer (such as retrieving files from a remote server via FTP, where I don't control or know the network delay or file sizes / count), I will wait for a fixed period of time between cycles.
Both are valid, but as pointed out earlier they do different things. The timer runs your code every x milliseconds, even if the previous instance hasn't finished. The Thread.Sleep(x) waits for a period of time after completing each iteration, so the total delay per loop will always be longer (perhaps not by much) than the sleep period.
I required a thread to fire once every minute (see question here) and I've now used a DispatchTimer based on the answers I received.
The answers provide some references which you might find useful.
I agree as well, using a timer is the best option. I have tried a solution similar to yours in the past and started having issues where the loop would misfire, and I would have to wait for another Thread.Sleep() before it would fire again. Also, it did cause all sorts of issues with stopping the service, I would get constant errors about how it wasn't responding and had to be closed.
#Prashanth's code should be exactly what you need.
You can use either one. But I think Sleep() is easy, clear and shorter to implement.
I would have to say a sleep is a better implementation with a state machine behind it. This would still keep you in control of the application at all times, but allowing any response needed at any specific time. This also will handle timer callbacks that are shorter than the "Processing execution time in the loop"
For example..
<!-- language: c# -->
public enum State
{
Idle = 0,
Processing = 1,
Stop = 100,
}
public void Run()
{
State state = State.Idle; // could be a member variable, so a service could stop this too
double intervalInSeconds = 60;
System.DateTime nextExecution = System.DateTime.Now.AddSeconds(intervalInSeconds);
while (state != State.Stop)
{
switch (state)
{
case State.Idle:
{
if (nextExecution > System.DateTime.Now)
{
state = State.Processing;
}
}
break;
case State.Processing:
{
// do your once-per-minute code here
// if you want it to stop, just set it state to stop.
// if this was a service, you could stop execution by setting state to stop, also
// only time it would not stop is if it was waiting for the process to finish, which you can handle in other ways
state = State.Idle;
nextExecution = System.DateTime.Now.AddSeconds(intervalInSeconds);
}
break;
default:
break;
}
System.Threading.Thread.Sleep(1);
}
}
Related
i have to keep running a method for 24x7.Basically the
application should process 40 data in every second, by using some thread.
i can use while or recursive call ling the same method. but in both process
the cpu uses getting too high almost 95-100 %. i can't use timer because
then the processing threads are not working properly. as per the provided solution
many people talk to use the while with thread sleep. but if i use thread sleep
then it getting delay in every iteration. i am using c# 4.0.
my question: is there any better solution to reduce the cpu uses?
the main method:
static void Main(string[] args)
{
while(true)
{
processData();
Thread.sleep(1000);
// here i use a 1 second sleep just for give a breath of CPU.
//But this one second sleep make me delay for enter data processing.
// I am looking for a better solution that no sleep time will use and CPU usages will getting low.
}
}
//Method should run always
static string processData()
{
{
// Open and close threads to process the data in every second.
}
// processData(); // it can be used for recursive method calling
}
but if i use thread sleep then it getting delay in every iteration. i am using c# 4.0.
You can use Thread.Sleep(0), which indicates:
that this thread should be suspended to allow other waiting threads to execute.
static void Main(string[] args)
{
while(true)
{
processData();
Thread.sleep(0);
}
}
This will allow the thread to give up some processing to other threads, prevent it from using 100% of the CPU, but still allow it to run at nearly full speed.
Note that using any delay, while it will reduce the overall CPU usage, will slow down the total throughput. The only way to maximize throughput would be allow it to spin non-stop, which of course will keep the CPU usage very high.
Using a System.Threading.Timer you are able to tell it when to next execute, e.g:
System.Threading.Timer myTimer = new System.Threading.Timer(~~~)
inside myTimer callback:
myTimer.Change(nextRunTime, newInterval);
This will run the code next in nextRunTime, and the interval will become newInterval.
More information on the "Change" method available here:
http://msdn.microsoft.com/en-us/library/7hs7492w.aspx
And on System.Threading.Timer:
http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx
Enjoy :)
Apologies if I'm being presumptuous, I'm of the impression that the reason you won't use a Timer is because there is always a fixed delay, but using this method you can adjust the delay each time it runs.
Anyways, if you're having issues with the Timer not processing correctly, can you share what exactly is going wrong there? May be able to help with that, and in the end use a Timer or similar.
static void Main(string[] args)
{
while(true)
{
var beginTime = DateTime.Now;
processData();
var duration = DateTime.Now.Subtract( beginTime );
// if you want to run 40 times per second,
// you need to spend 1000/40 = 25ms per iteration
var sleepDuration = (int)(25 - duration.TotalMilliseconds);
if( 0 < sleepDuration )
{
Thread.sleep(sleepDuration);
}
}
}
Edit: as suggested in another answer, you could use the Timer class if your processData() method is thread safe
this below code can be a appropriate solution in this case. For more detail please check this link.
uint loops = 0;
while (true)
{
if (Environment.ProcessorCount == 1 || (++loops % 100) == 0)
{
processData();
Thread.Sleep(1);
}
else
{
processData();
Thread.SpinWait(20);
}
}
I have a function that needs to archive 90 day old emails every midnight. I created a class to handle this and here's the example:
public void processArchives()
{
initializeTimer();
}
private void initializeTimer()
{
var now = DateTime.Now;
var tomorrow = now.AddDays(1);
var durationUntilMidnight = tomorrow.Date - now;
var t = new Timer(o => { attemptArchivalProcess(); }, null, TimeSpan.Zero, durationUntilMidnight);
}
private void attemptArchivalProcess()
{
//perform archival
initializeTimer(); //re-start timer to process tomorrow
}
question is, will the repeated calls to initializeTimer cause a stack overflow (repeated function calls) or will it run fine 'forever'?
and should I be able to call processArchives() as a new thread, and keep the thread open or do I need some sort of loop after the init call something like:
while(!Program.Closing){ sleep(...); }
to keep it from being garbage collected?
I think you are close to your potential solution.
Timer
To answer your first question: As you already concluded the timer will elapse on it's delegate. The delegate will be executed on a separate thread and each timer elapse will get a brand new fresh own stack to execute on. Thus, endless timer elapsed events will never trigger a StackOverflowException.
Wait until forever?
An attempt to answer your second question: You don't have to write an endless loop to keep your application alive. But, you could do that, it all depends on what you need for your application. Weigh the pros and cons.
Luckily there are more solutions possible (there is no right or wrong, weigh them out to fulfill your needs)
A shot list of solutions you could concider:
Console.ReadLine()
If you have a console application, you could simply wait for user input. The main thread will wait forever without consuming processor power.
As suggested by Servy, create a scheduled task
That way you don't have to do anything at all to write endless loops. Your application will simply exit when it's done. Might not be the most handsome solution if you actually deploy this app to users.
Windows service
You could also go for a bit more mature solution and write a windows service (sounds more complicated than it is, it's pretty simple to write a basic windows service). That way you also don't have to bother about writing never ending loops, a windows service will run forever by design (unit you decide to stop it of course)
Alternative for never ending while loop - WaitHandle
You could also use a signal mechanism (e.g. with a AutoResetEvent) so that your main thread can Wait until a certain signal is set. That way you also don't have to actively wait (=not consume processor cycles).
You have tons of alternatives, it all boils down to your specific needs, which I can't decide for you. You can. :)
All those words, let's throw in an example. The unit test represents your application. The timer is a different type, namely the System.Timers.Timer. You can set that timer to AutoReset so that you don't have to create new timers.
Here the example, I hope it makes sense to you (if not, comment, maybe I can clarify)
private Timer _processTimer;
private AutoResetEvent _resetSignal;
[Test]
public void YourImaginaryMainApp()
{
const int interval = 24 * 60 * 60 * 1000; // every day
_resetSignal = new AutoResetEvent(false);
_processTimer = new Timer(interval)
{
AutoReset = true
};
_processTimer.Elapsed += ProcessTimerOnElapsed;
_resetSignal.WaitOne( /*infinite*/);
}
Edit x1 - meant "heap", not "stack" in second sentence... (d'oh!)
I don't think this will cause a stack overflow for a very simple reason. The line var t = new Timer(... creates a new object on the heap. The function pointer is kept internally within the object and should (in theory) never be added to the stack until it's actually called. When attemptArchivalProcess() is called, it in turns calls initializeTimer() (adding to the stack) but this then completes and exits as normal on the same thread (removing from the stack). When the Timer does kick in, it'll start off that 2-call entry to the stack.
Now, all this said, I know there is increased complexity going on under the hood with the stack but my point is that ultimately that you have 2 methods being called which then exit correctly - and should be cleaned up correctly when they exit.
Or at least that's my reasoning. I fully admit I'm open to correction on this though...
Here's my attempted resolution for this....
System.Threading.Timer timerFunc = null;
public void processArchives()
{
initializeTimer();
while (!CSEmailQueues.StoppingService) //is
Thread.Sleep(CSEmailQueues.sleeptime);
timerFunc.Dispose();
return;
}
private void initializeTimer()
{
var now = DateTime.Now;
var tomorrow = now.AddDays(1);
var durationUntilMidnight = tomorrow.Date - now;
if (timerFunc != null) timerFunc.Dispose();
timerFunc = new System.Threading.Timer(o => { attemptArchivalProcess(); }, null, TimeSpan.Zero, durationUntilMidnight);
}
private void attemptArchivalProcess()
{
//Do Work
initializeTimer(); //re-start timer to process tomorrow
}
So...this will dispose the timer object and create a new one each time it runs (as this timer only executes once). Plus being a class level variable, there is always a reference to the timer so the garbage collector doesn't dispose of it while i'm waiting for it to trigger.
Then all I have to do is create a thread that calls processArchives() from the onStart call for the service, and this should in essence run forever unless the onStop is called and sets StoppingService to true.
Also I am guessing I shouldn't have to worry about cross-thread use of timerFunc by the timer callback as there should never be more than 1 instance at any given time to access this object.
I'm currently building a Windows Service which needs to process a queue of messages that are sat in a database table. This queue could vary in length and could take anything from 5 seconds to 55 seconds to execute against all rows in the database (I'm currently using a test data set of 500,000 records)
The Windows Service is configured to run on a 30 second timer so I have tried, unsuccessfully, to ensure that when the timer delegate runs that it is not able to run again until the previous request to the method has completed successfully
I have the following code in my Windows Service OnStart method:
AutoResetEvent autoEvent = new AutoResetEvent(false);
TimerCallback timerDelegate = new TimerCallback(MessageQueue.ProcessQueue);
Timer stateTimer = new Timer(timerDelegate, autoEvent, 1000, Settings.Default.TimerInterval); // TimerInterval is 30000
autoEvent.WaitOne();
And the following code in MessageQueue.ProcessMessage:
Trace.Write("Starting ProcessQueue");
SmtpClient smtp = new SmtpClient("winprev-01");
AutoResetEvent autoEvent = (AutoResetEvent)stateObject;
foreach (MessageQueue message in AllUnprocessed)
{
switch (message.MessageType)
{
case MessageType.PlainText:
case MessageType.HTML:
SendEmail(smtp, message);
break;
case MessageType.SMS:
SendSms(message);
break;
default:
break;
}
}
autoEvent.Set();
Trace.Write("Ending ProcessQueue");
I'm using DebugView to analyse the view the Trace statements as the Service runs and I can see multiple instances of "Starting ProcessQueue" which occur every 30 seconds which is what I am trying to avoid happening
In summary: I want to call ProcessQueue and ensure that it is not executed again unless it has completed its work (this enables me to prevent the same messages in the queue being processed multiple times
I'm sure I'm missing something pretty obvious here so any help would be much appreciated :)
Dave
Why don't you have your delegate disable the timer and then re-enable it (or continue working, if timer would expire immediately) once it's through working. Provided the latency between timer firing and your delegate waking up is < 30 seconds, this should be watertight.
while (true)
{
Trace.Write("Starting ProcessQueue")
stateTimer.Enabled = false;
DateTime start = DateTime.Now;
// do the work
// check if timer should be restarted, and for how long
TimeSpan workTime = DateTime.Now - start;
double seconds = workTime.TotalSeconds;
if (seconds > 30)
{
// do the work again
continue;
}
else
{
// Restart timer to pop at the appropriate time from now
stateTimer.Interval = 30 - seconds;
stateTimer.Enabled = true;
break;
}
}
Your ProcessMessage is never checking if the resetEvent is signaled - it's just running regardless.
I post here how to fix this. However, this is not the ideal method to do what you want to do. See the bottom of my answer for that.
You have your call to autoEvent.WaitOne() in the wrong place; it should be at the beginning of the ProcessMessage method.
AutoResetEvent autoEvent = (AutoResetEvent)stateObject;
autoEvent.WaitOne();
Trace.Write("Starting ProcessQueue");
SmtpClient smtp = new SmtpClient("winprev-01");
foreach (MessageQueue message in AllUnprocessed){
You should also use the overload that accepts a time out value (int or timespan), and returns a bool If the method returns true, that means it was signaled, so you can continue. If it times out (because another iteration is still running), you should just return and not try to run the code again.
If you do not use such an overload, what you are doing would be no different than wrapping the ProcessMessage method's code in a critical section (lock() on a global var, for instance) - additional threads would block, and then needlessly run.
AutoResetEvent autoEvent = (AutoResetEvent)stateObject;
//wait just one ms to see if it gets signaled; returns false if not
if(autoEvent.WaitOne(1)){
Trace.Write("Starting ProcessQueue");
SmtpClient smtp = new SmtpClient("winprev-01");
foreach (MessageQueue message in AllUnprocessed){
Note that actually, a *ResetEvent isn't ideal here. You really just want to check if an instance is already running, and abort if so. ResetEvents aren't really made for that... but I wanted to address the question of using the ResetEvent anyway.
What would probably work better is to simply shut down the timer when the callback is called, and then restart it up when you are done. That way, it's impossible for that code to be re-entered while it's still running.
You absolutely would need to wrap all the code in the callback method in a try / finally though, so that you always restart the timer after.
You can trivially solve this by using a System.Threading.Timer. You make it a one-shot timer by setting its period to zero. Restart the timer in the callback. Overlapped execution of the callback is now impossible.
Since you run this so frequently, a different approach is to use a thread instead. You'll need an AutoResetEvent to signal the thread to stop in the OnStop() method. Its WaitOne() method gives you a free timer when you use the overload that takes the millisecondsTimeout argument.
Btw: note that the autoEvent.WaitOne() call in OnStart() is troublesome. It may timeout the service controller if the first email takes a long time to send. Just omit it, you got the timer started == service started.
I think you are making this a lot harder than it needs to be. Why not just create a separate thread that spins around an infinite loop calling MessageQueue.ProcessQueue and then waiting a certain amount of time before calling it again. If it is all happening on a single thread there is no way for anything to happen in parallel.
public class YourService : ServiceBase
{
private ManualResetEvent m_Stop = new ManualResetEvent(false);
protected override void OnStart(string[] args)
{
new Thread(Run).Start();
}
protected override void OnStop()
{
m_Stop.Set();
}
private void Run()
{
while (!m_Stop.WaitOne(TimeSpan.FromSeconds(30))
{
MessageQueue.ProcessMessage();
}
}
}
OnStart method
AutoResetEvent autoEvent = new AutoResetEvent(true);
while (true)
{
autoEvent.WaitOne();
Thread t = new Thread(MessageQueue.ProcessMessage);
t.Start(autoEvent);
}
What you want is a synchronization timer object. In Win32 this is known as a waitable timer (unfortunately some P/invoke is required, unless I'm mistaken).
Here's what you would do:
Create waitable timer (make sure it's auto-reset).
Set waitable timer with a period of 30 seconds.
Loop:
WaitForSingleObject(waitable timer) with infinite timeout.
Process queue.
If the processing takes more than 30s, the timer will simply remain set until you call WaitForSingleObject on it. Additionally, if the processing takes 20s for example, the timer will be signaled after 10 more seconds.
I'm hoping someone can shed some light on what might be happening for me. Here's a summary of whats happening.
I have an application that does lots of "stuff". Its a pretty hefty application that does lots of number crunching using many threads. There are several timers that are used. Over a long period of time, the timers stop consistently invoking the elapsed handler.
For instance: I have a timer set to elapse every second. After a period of hours the timer starts randomly triggering late. If I do not restart the application the performance just degrades and the timers fire later and later eventually turning into 3 or 4 seconds, forcing me to restart the application. I have not been able to identify any leaks. CPU usage does not go up, memory does not go up, and the server is no where near being maxed out. Can anyone give me some ideas as to what may be causing this?
private void Timer_Elapsed(object source, ElapsedEventArgs e)
{
if (seconds > 0)
{
seconds--;
timer.Start();
}
}
Is it possible you're exhausting the thread pool? Most timers invoke the handler using a threadpool thread. If all threadpool threads are in use, it will just get queued until one is available.
If that's the case switch some of your processing to use your own threads, not threadpool threads.
To test if you're exhausting the thread pool start up a background thread that periodically (a few times a second) checks ThreadPool.GetAvailableThreads and logs a message when the available is small (even if it's never actually zero when you check, if it sometimes approaches zero then it's likely this is the problem).
The size of the pool can be changed with ThreadPool.SetMaxThreads although that may not be the best solution. If you're using threadpool threads for longer running tasks, stop it. For long-running tasks use your own threads.
the timer class you use is really important
http://msdn.microsoft.com/en-us/magazine/cc164015.aspx
but I don't think the problem is the timer itself,
for instance try making an application using the same timer class
that ONLY writes the current DateTime to a log file
and leave it running for an extremely long period of time, you'll see that there's no such a 3/4 seconds delay
review your timer code and check that no shared resources are being accessed at the same time,
maybe the Timer is OK, but there's a bottleneck in the event handler function or in "something" that function uses
Sounds like maybe it's not really the same timer, and so the resources being "leaked" here are GDI handles.
Possible workaround:
DateTime mayContinue = DateTime.MinValue;
bool blockingUi = false;
private void Timer_Elapsed(object source, ElapsedEventArgs e)
{
if( blockingUi )
{
if( DateTime.Now < mayContinue )
{
// Notify time remaining
// Update the UI with a BeginInvoke
}
else
{
blockingUi = false;
// Notify ready
// Update the UI with a BeginInvoke
}
}
}
private void BlockUi()
{
mayContinue = DateTime.Now.AddSeconds(30);
blockingUi = true;
}
I am aware that System.Threading.Timer exists, but I already have a Thread. This thread is supposed to stay alive all the time, but only execute every X seconds. The test implementation looks like this:
public class MailClass
{
private Action<string> LoggerAction;
private bool _exit;
public MailClass(Action<string> loggerAction)
{
LoggerAction = loggerAction;
}
public void Run()
{
LoggerAction("Run called");
_exit = false;
while(!_exit)
{
Thread.Sleep(TimeSpan.FromSeconds(300));
LoggerAction("Waking up");
}
LoggerAction("Run ended");
}
public void Stop()
{
LoggerAction("Stop called");
_exit = true;
}
}
The Run method executes, then sleeps for 5 Minutes, then executes again. So it's basically a timer that fires every 5 Minutes + the time it takes to execute the action. (and yes, I should cache the TimeSpan instead of re-creating it over and over)
Is this the proper way to do it? (In the real app, the Run action checks a Web Service, so I have no way to signal my Thread to wake up earlier)
Or should I use some other concept to have the thread? One problem I see is the implementation of Stop. The Run Thread runs a loop that checks a bool every time, but if I call Stop() I have to wait until the Sleep Interval is over, which is inconvenient.
Thread.Abort would be harsh, so I guess Thread.Interrupt would work somehow? The Stop() Method should allow Run to finish it's current iteration, so no hard abort. AutoResetEvent looks a bit like what I could need, but I don't fully understand what it does.
Edit: One way I would see this possible is to add a Timer (so a separate thread) and then have Run() end not with Thread.Sleep but with some "Wait until some object changes". I would then change that object either from the second Thread (when the 5 minutes expire) or from the Stop action. But that seems excessive? Essentially, Run needs to react to two conditions: 5 Minutes expire or some external signal (like the change of the _exit flag). Something tells me there should be something built-in, but maybe having another Timer Thread solely focused on sending a signal every 5 minutes is the way to go?
If you're forced to poll, then you're forced to poll. Thread.Sleep() is fine for that.
However with regards to you're interrupt concerns...
I'd re-write your solution a bit to use Monitor.Wait/Pulse. That does require you keep an object around solely to lock(...){} on it, but it strikes me as a cleaner solution.
I say cleaner because using Thread.Interrupt() is effectively using exceptions for "normal" control flow. Stopping a Timer is in no way unexpected. But its a design smell really (if such things exist), nothing more.
Quicky outline:
//Instead of Thread.Sleep(FIVE_MIN) in Run()...
lock(some_obj)
{
if(Monitor.Wait(some_obj, FIVE_MIN)) //Wait for 5 min (or whatever) or until some_obj is Pulse'd
{
//Got Pulse
}
else
{
//Timeout expired
}
}
//And in Stop()...
_exit = true;
lock(some_obj)
{
Monitor.Pulse(some_obj); //Wakeup the thread in Run() if it's currently Wait'ing
}
yeah that's cool, you can also call Thread.Interrupt() to interrupt the sleep, rather than waiting for sleep to return normally.
in the case the thread is not blocking when you interrupt it, it will continue processing normally until it tries to sleep again.
Is there a reason you couldn't just use a timer inside the thread? You'd get what you want, a thread that stays alive forever while firing off your method, plus you could just stop the timer at any point without waiting for 5 minutes or interrupting threads?
(I'm not very experienced in threading, so I might be missing something obvious?)
If time interval is critical then prefer high resolution timers provided in windows which will trigger with higher accuracy.
Seems like a good solution to me. If you're worried about stopping sooner, you can set the sleep time to be less and keep a count so you only run the actual code every 5 minutes. That way it's checking the boolean more often and can break out sooner.
You could look into System.Timers.Timer as well, though truthfully just sleeping is not a bad solution.