what is the best way to keep running a method - c#

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

Related

Is thread sleeping in while(true) loop a bad way to reduce cpu usage? [duplicate]

I have a unit of work I'm doing in a thread (not the main thread). Under certain circumstances I would like to put this thread to sleep for 10 seconds. Is Thread.Sleep(10000) the most resource efficient way to do this?
Is Thread.Sleep(10000) the most resource efficient way to do this?
Yes in the sense that it is not busy-waiting but giving up the CPU.
But it is wasting a Thread. You shouldn't scale this to many sleeping threads.
As no-one else has mentioned it...
If you want another thread to be able to wake up your "sleeping" thread, you may well want to use Monitor.Wait instead of Thread.Sleep:
private readonly object sharedMonitor;
private bool shouldStop;
public void Stop()
{
lock (sharedMonitor)
{
shouldStop = true;
Monitor.Pulse(sharedMonitor);
}
}
public void Loop()
{
while (true)
{
// Do some work...
lock (sharedMonitor)
{
if (shouldStop)
{
return;
}
Monitor.Wait(sharedMonitor, 10000);
if (shouldStop)
{
return;
}
}
}
}
Note that we only access shouldStop within the lock, so there aren't any memory model concerns.
You may want to loop round waiting until you've really slept for 10 seconds, just in case you get spurious wake-ups - it depends on how important it is that you don't do the work again for another 10 seconds. (I've never knowingly encountered spurious wakes, but I believe they're possible.)
Make a habit of using Thread.CurrentThread.Join(timeout) instead of Thread.Sleep.
The difference is that Join will still do some message pumping (e.g. GUI & COM).
Most of the time it doesn't matter but it makes life easier if you ever need to use some COM or GUI object in your application.
This will process something every x seconds without using a thread
Not sure how not using your own thread compares with a task to run that is created every two seconds
public void LogProcessor()
{
if (_isRunning)
{
WriteNewLogsToDisk();
// Come back in 2 seonds
var t = Task.Run(async delegate
{
await Task.Delay(2000);
LogProcessor();
});
}
}
From resource efficiency, yes.
For design, it depends on the circumstances for the pause. You want your work to be autonomous so if the thread has to pause because it knows to wait then put the pause in the thread code using the static Thread.Sleep method. If the pause happens because of some other external event than you need to control the thread processing, then have the thread owner keep reference to the thread and call childThread.Sleep.
Yes. There's no other efficient or safe way to sleep the thread.
However, if you're doing some work in a loop, you may want to use Sleep in loop to make aborting the thread easier, in case you want to cancel your work.
Here's an example:
bool exit = false;
...
void MyThread()
{
while(!exit)
{
// do your stuff here...
stuff...
// sleep for 10 seconds
int sc = 0;
while(sc < 1000 && !exit) { Thread.Sleep(10); sc++; }
}
}

CPU friendly infinite loop

Writing an infinite loop is simple:
while(true){
//add whatever break condition here
}
But this will trash the CPU performance. This execution thread will take as much as possible from CPU's power.
What is the best way to lower the impact on CPU?
Adding some Thread.Sleep(n) should do the trick, but setting a high timeout value for Sleep() method may indicate an unresponsive application to the operating system.
Let's say I need to perform a task each minute or so in a console app.
I need to keep Main() running in an "infinite loop" while a timer will fire the event that will do the job. I would like to keep Main() with the lowest impact on CPU.
What methods do you suggest. Sleep() can be ok, but as I already mentioned, this might indicate an unresponsive thread to the operating system.
LATER EDIT:
I want to explain better what I am looking for:
I need a console app not Windows service. Console apps can simulate the Windows services on Windows Mobile 6.x systems with Compact Framework.
I need a way to keep the app alive as long as the Windows Mobile device is running.
We all know that the console app runs as long as its static Main() function runs, so I need a way to prevent Main() function exit.
In special situations (like: updating the app), I need to request the app to stop, so I need to infinitely loop and test for some exit condition. For example, this is why Console.ReadLine() is no use for me. There is no exit condition check.
Regarding the above, I still want Main() function as resource friendly as possible. Let asside the fingerprint of the function that checks for the exit condition.
To avoid the infinity loop simply use a WaitHandle. To let the process be exited from the outer world use a EventWaitHandle with a unique string. Below is an example.
If you start it the first time, it simple prints out a message every 10 seconds. If you start in the mean time a second instance of the program it will inform the other process to gracefully exit and exits itself also immediately. The CPU usage for this approach: 0%
private static void Main(string[] args)
{
// Create a IPC wait handle with a unique identifier.
bool createdNew;
var waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, "CF2D4313-33DE-489D-9721-6AFF69841DEA", out createdNew);
var signaled = false;
// If the handle was already there, inform the other process to exit itself.
// Afterwards we'll also die.
if (!createdNew)
{
Log("Inform other process to stop.");
waitHandle.Set();
Log("Informer exited.");
return;
}
// Start a another thread that does something every 10 seconds.
var timer = new Timer(OnTimerElapsed, null, TimeSpan.Zero, TimeSpan.FromSeconds(10));
// Wait if someone tells us to die or do every five seconds something else.
do
{
signaled = waitHandle.WaitOne(TimeSpan.FromSeconds(5));
// ToDo: Something else if desired.
} while (!signaled);
// The above loop with an interceptor could also be replaced by an endless waiter
//waitHandle.WaitOne();
Log("Got signal to kill myself.");
}
private static void Log(string message)
{
Console.WriteLine(DateTime.Now + ": " + message);
}
private static void OnTimerElapsed(object state)
{
Log("Timer elapsed.");
}
You can use System.Threading.Timer Class which provides ability to execute callback asynchronously in a given period of time.
public Timer(
TimerCallback callback,
Object state,
int dueTime,
int period
)
As alternative there is System.Timers.Timer class which exposes Elapsed Event which raises when a given period of time is elapsed.
Why would you condone the use of an infinite loop? For this example would setting the program up as a scheduled task, to be run every minute, not be more economical?
Why don't you write a small application and use the system's task scheduler to run it every minute, hour...etc?
Another option would be to write a Windows Service which runs in the background. The service could use a simple Alarm class like the following on MSDN:
http://msdn.microsoft.com/en-us/library/wkzf914z%28v=VS.90%29.aspx#Y2400
You can use it to periodically trigger your method. Internally this Alarm class uses a timer:
http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx
Just set the timer's interval correctly (e.g. 60000 milliseconds) and it will raise the Elapsed event periodically. Attach an event handler to the Elapsed event to perform your task. No need to implement an "infinite loop" just to keep the application alive. This is handled for you by the service.
I did this for an application that had to process files as they were dropped on a folder. Your best bet is a timer (as suggested) with a Console.ReadLine() at the end of "main" without putting in a loop.
Now, your concern about telling the app to stop:
I have also done this via some rudimentary "file" monitor. Simply creating the file "quit.txt" in the root folder of the application (by either my program or another application that might request it to stop) will make the application quit. Semi-code:
<do your timer thing here>
watcher = new FileSystemWatcher();
watcher.Path = <path of your application or other known accessible path>;
watcher.Changed += new FileSystemEventHandler(OnNewFile);
Console.ReadLine();
The OnNewFile could be something like this:
private static void OnNewFile(object source, FileSystemEventArgs e)
{
if(System.IO.Path.GetFileName(e.FullPath)).ToLower()=="quit.txt")
... remove current quit.txt
Environment.Exit(1);
}
Now you mentioned that this is (or could be) for a mobile application? You might not have the file system watcher. In that case, maybe you just need to "kill" the process (you said "In special situations (like: updating the app), I need to request the app to stop". Whoever the "requester" to stop it is, should simply kill the process)
It sounds to me like you want Main() to enter an interruptable loop. For this to happen, multiple threads must be involved somewhere (or your loop must poll periodically; I am not discussing that solution here though). Either another thread in the same application, or a thread in another process, must be able to signal to your Main() loop that it should terminate.
If this is true, then I think you want to use a ManualResetEvent or an EventWaitHandle . You can wait on that event until it is signalled (and the signalling would have to be done by another thread).
For example:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Demo
{
class Program
{
static void Main(string[] args)
{
startThreadThatSignalsTerminatorAfterSomeTime();
Console.WriteLine("Waiting for terminator to be signalled.");
waitForTerminatorToBeSignalled();
Console.WriteLine("Finished waiting.");
Console.ReadLine();
}
private static void waitForTerminatorToBeSignalled()
{
_terminator.WaitOne(); // Waits forever, but you can specify a timeout if needed.
}
private static void startThreadThatSignalsTerminatorAfterSomeTime()
{
// Instead of this thread signalling the event, a thread in a completely
// different process could do so.
Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
_terminator.Set();
});
}
// I'm using an EventWaitHandle rather than a ManualResetEvent because that can be named and therefore
// used by threads in a different process. For intra-process use you can use a ManualResetEvent, which
// uses slightly fewer resources and so may be a better choice.
static readonly EventWaitHandle _terminator = new EventWaitHandle(false, EventResetMode.ManualReset, "MyEventName");
}
}
You can use Begin-/End-Invoke to yield to other threads. E.g.
public static void ExecuteAsyncLoop(Func<bool> loopBody)
{
loopBody.BeginInvoke(ExecuteAsyncLoop, loopBody);
}
private static void ExecuteAsyncLoop(IAsyncResult result)
{
var func = ((Func<bool>)result.AsyncState);
try
{
if (!func.EndInvoke(result))
return;
}
catch
{
// Do something with exception.
return;
}
func.BeginInvoke(ExecuteAsyncLoop, func);
}
You would use it as such:
ExecuteAsyncLoop(() =>
{
// Do something.
return true; // Loop indefinitely.
});
This used 60% of one core on my machine (completely empty loop). Alternatively, you can use this (Source) code in the body of your loop:
private static readonly bool IsSingleCpuMachine = (Environment.ProcessorCount == 1);
[DllImport("kernel32", ExactSpelling = true)]
private static extern void SwitchToThread();
private static void StallThread()
{
// On a single-CPU system, spinning does no good
if (IsSingleCpuMachine) SwitchToThread();
// Multi-CPU system might be hyper-threaded, let other thread run
else Thread.SpinWait(1);
}
while (true)
{
// Do something.
StallThread();
}
That used 20% of one core on my machine.
To expound on a comment CodeInChaos made:
You can set a given thread's priority. Threads are scheduled for execution based on their priority. The scheduling algorithm used to determine the order of thread execution varies with each operating system. All threads default to "normal" priority, but if you set your loop to low; it shouldn't steal time from threads set to normal.
The Timer approach is probably your best bet, but since you mention Thread.Sleep there is an interesting Thread.SpinWait or SpinWait struct alternative for similar problems that can sometimes be better than short Thread.Sleep invocations.
Also see this question: What's the purpose of Thread.SpinWait method?
Lots of "advanced" answers here but IMO simply using a Thread.Sleep(lowvalue) should suffice for most.
Timers are also a solution, but the code behind a timer is also an infinity loop - I would assume - that fires your code on elapsed intervals, but they have the correct infinity-loop setup.
If you need a large sleep, you can cut it into smaller sleeps.
So something like this is a simple and easy 0% CPU solution for a non-UI app.
static void Main(string[] args)
{
bool wait = true;
int sleepLen = 1 * 60 * 1000; // 1 minute
while (wait)
{
//... your code
var sleepCount = sleepLen / 100;
for (int i = 0; i < sleepCount; i++)
{
Thread.Sleep(100);
}
}
}
Regarding how the OS detects if the app is unresponsive. I do not know of any other tests than on UI applications, where there are methods to check if the UI thread processes UI code. Thread sleeps on the UI will easily be discovered. The Windows "Application is unresponsive" uses a simple native method "SendMessageTimeout" to see detect if the app has an unresponse UI.
Any infinity loop on an UI app should always be run in a separate thread.
To keep console applications running just add a Console.ReadLine() to the end of your code in Main().
If the user shouldn't be able to terminate the application you can do this with a loop like the following:
while (true){
Console.ReadLine();
}

Is "while (true)" usually used for a permanent thread?

I'm relatively new to coding; most of my "work" has been just simple GUI apps that only function for one thing, so I haven't had to thread much.
Anyway, one thing I'm wondering about threading is if you want to keep a thread alive forever to do whatever job it's doing (processing, waiting for input, whatever), is it normal to format it like so:
while (true) {
// do stuff
Thread.Sleep(1000);
}
(or something along those lines)...? Or is this not safe and should it be avoided if possible?
Yep, that's what you do.
But typically it's like:
bool keepRunning = true;
...
while(keepRunning){
}
Because sometimes you may like to have someone/something else to have the ability to stop you.
To elaborate a bit more, if a thread is sleeping, when the OS comes along to activate the thread, it will just check to see if it's still sleeping and if so, then just yield its timeslice.
If you leave out the Sleep and do something like
while (true)
{
if (workAvailable)
{
doWork();
}
}
then even if workAvailable is false it will keep spinning until the OS stops it, taking up its entire slice doing nothing. Obviously that's a little more inefficient.
You can get even more complex as needed with mutexes, semaphores and whatnot, as mentioned above, but things get complex quickly with those, so you might want to use them to solve a particular problem.
Additionally You can use System.Threading.Timer. In this case, we don't have to use the Sleep method. Simple example:
public sealed class TimerTask
{
private Timer _timer;
private int _period;
public TimerTask(int period)
{
_period = period;
_timer = new Timer(new TimerCallback(Run), "Hello ....", Timeout.Infinite, period);
}
public void Start()
{
_timer.Change(0, _period);
}
public void Stop()
{
_timer.Change(Timeout.Infinite, Timeout.Infinite);
}
private void Run(Object param)
{
Console.WriteLine(param.ToString());
}
}
Use:
public static class Program
{
[STAThread]
static void Main(String[] args)
{
TimerTask task = new TimerTask(1000);
Console.WriteLine("Timer start.");
task.Start();
Console.ReadLine();
Console.WriteLine("Timer stop.");
task.Stop();
Console.ReadLine();
Console.WriteLine("Timer start.");
task.Start();
Console.ReadLine();
Console.WriteLine("Timer stop.");
task.Stop();
Console.ReadLine();
}
}
Console output:
Timer start.
Hello ....
Hello ....
Hello ....
Timer stop.
Timer start.
Hello ....
Hello ....
Timer stop.
Ideally you want the thread to be "runnable" when it has work to do, and "sleeping" when there is nothing to do.
This is best done with objects like mutual exclusions (mutexes), semaphores and condition variables, which provide mechanisms for threads to wake other threads up when there may be something for them to do.
Just doing a timed sleep is inefficient, because a short sleep means the thread wastes time waking up to check if there's work to do, while a long sleep means the thread might be asleep while there's work to be done. Usually this is not a big deal but if the code deals with large volumes of requests or data things don't go so well.
A basic model works like this: Thread A puts objects in a queue. Thread B removes an object from the queue, performs an action, and repeats. If there are no objects in the queue, thread B will remain asleep until an object arrives.
You must also be careful that threads which access shared stuff avoid race conditions.
I can't give any C#-specific insight, but I know that C# gives you some tools to help you out.
Just as some additional info, typical none ending loops use
for(;;)
{
...
}
as there is no compare done in the loop. When doing threads it is best to check a flag if the loop to end or not though.
I had the same problem and tried several methods, keeping an eye on the CPU % which in my case was really important. Here the results:
while (true) {} //this is the worst CPU-consuming one: 30% in my case.
The above, in terms of performance, is the worst (takes more CPU % than any other method, 30% on my project, on my pc). Much better the next one:
while (true) {thread.sleep(1);} //5% cpu, in my case
The above is good in terms of CPU % (around 5% in my case), but not very much elegant:
Console.Readline(); //4% cpu in my case, but for very specific projects
The above is usable only in specific cases, and it's good if you have a console .net application running on background that will never be able to capture a keypress. Still not much elegant, but takes around 4% of CPU in my particular case.
ManualResetEvent resetEvent = new ManualResetEvent(false);
resetEvent.WaitOne(); // WINNER: 4% cpu in my case, and very elegant also.
The above, in my opinion, is the best one: elegant and low CPU consuming (4% in my case). You simply wait for a resetEvent that will never happen. Low CPU% on waiting, and elegant. Also, you can make terminate the infinite waiting by calling "resetEvent.Set()", even from another thread...

Pausing a method for set # of milliseconds

I need to do a sort of "timeout" or pause in my method for 10 seconds (10000 milliseconds), but I'm not sure if the following would work as i do not have multi-threading.
Thread.Sleep(10000);
I will try to use that current code, but I would appreciate if someone could explain the best and correct way of doing this, especially if the above code does not work properly. Thanks!
UPDATE: This program is actually a console application that in the function in question is doing many HTTPWebRequests to one server, so I wish to delay them for a specified amount of milliseconds. Thus, no callback is required - all that is needed is an "unconditional pause" - basically just the whole thing stops for 10 seconds and then keeps going. I'm pleased that C# still considers this as a thread, so Thread.Sleep(...) would work. Thanks everybody!
You may not have multi-threading, but you're still executing within a thread: all code executes in a thread.
Calling Thread.Sleep will indeed pause the current thread. Do you really want it to unconditionally pause for 10 seconds, or do you want to be able to be "woken up" by something else happening? If you're only actually using one thread, calling Sleep may well be the best way forward, but it will depend on the situation.
In particular, if you're writing a GUI app you don't want to use Thread.Sleep from the UI thread, as otherwise your whole app will become unresponsive for 10 seconds.
If you could give more information about your application, that would help us to advise you better.
Thread.Sleep is fine, and AFAIK the proper way. Even if you are not Multithreaded: There is always at least one Thread, and if you send that to sleep, it sleeps.
Another (bad) way is a spinlock, something like:
// Do never ever use this
private void DoNothing(){ }
private void KillCPU()
{
DateTime target = DateTime.Now.AddSeconds(10);
while(DateTime.Now < target) DoNothing();
DoStuffAfterWaiting10Seconds();
}
This is sadly still being used by people and while it will halt your program for 10 seconds, it will run at 100% CPU Utilization (Well, on Multi-Core systems it's one core).
That will indeed pause the executing thread/method for 10 seconds. Are you seeing a specific problem?
Note that you shouldn't Sleep the UI thread - it would be better to do a callback instead.
Note also that there are other ways of blocking a thread that allow simpler access to get it going again (if you find it is OK after 2s); such as Monitor.Wait(obj, 10000) (allowing another thread to Pulse if needed to wake it up):
static void Main() {
object lockObj = new object();
lock (lockObj) {
new Thread(GetInput).Start(lockObj);
Monitor.Wait(lockObj, 10000);
}
Console.WriteLine("Main exiting");
}
static void GetInput(object state) {
Console.WriteLine("press return...");
string s = Console.ReadLine();
lock (state) {
Monitor.Pulse(state);
}
Console.WriteLine("GetInput exiting");
}
You can do this with Thread.Interrupt too, but IMO that is messier.
You could use a separate thread to do it:
ThreadPool.QueueUserWorkItem(
delegate(object state)
{
Thread.Sleep(1000);
Console.WriteLine("done");
});
But, if this is a Windows Forms app, you will need to invoke the code after the delay from the Gui thread (this article, for example: How to update the GUI from another thread in C#?).
[Edit] Just saw your update. If it's a console app, then this will work. But if you haven't used multiple threads so far, then you need to be aware that this code will be executed in a different thread, which means you will have to take care about thread synchronization issues.
If you don't need background workers, stick to "keeping it simple".
Here is a pause class that will pause for the desired milliseconds and wont consume your CPU resources.
public class PauseClass
{
//(C) Michael Roberg
//Please feel free to distribute this class but include my credentials.
System.Timers.Timer pauseTimer = null;
public void BreakPause()
{
if (pauseTimer != null)
{
pauseTimer.Stop();
pauseTimer.Enabled = false;
}
}
public bool Pause(int miliseconds)
{
ThreadPriority CurrentPriority = Thread.CurrentThread.Priority;
if (miliseconds > 0)
{
Thread.CurrentThread.Priority = ThreadPriority.Lowest;
pauseTimer = new System.Timers.Timer();
pauseTimer.Elapsed += new ElapsedEventHandler(pauseTimer_Elapsed);
pauseTimer.Interval = miliseconds;
pauseTimer.Enabled = true;
while (pauseTimer.Enabled)
{
Thread.Sleep(10);
Application.DoEvents();
//pausThread.Sleep(1);
}
pauseTimer.Elapsed -= new ElapsedEventHandler(pauseTimer_Elapsed);
}
Thread.CurrentThread.Priority = CurrentPriority;
return true;
}
private void pauseTimer_Elapsed(object sender, ElapsedEventArgs e)
{
pauseTimer.Enabled = false;
}
}
Yes, that works just fine.
You don't have to have multiple threads to make use of some of the methods in the Thread class. You always have at least one thread.
For a timeout, you should have a static volatile boolean isRunning class field. When the new thread starts, the isRunning must become true, and at the end must become false.
The main thread should have a method that loops for the isRunning during the timeout you define. When the timeout ends, you should implement the logic. But, never use the abort thread method.
A pause... there isn't a straightforward solution. It depends on what you are doing inside the thread. However, you could look at Monitor.Wait.
If you can have an async method, you can do something like to pause the function at a certain location. Once pause is set false it will continue executing the rest of the code in the method. Since this is an async method and delay is async too UI execution wouldn't be affected.
* Please note that asyn is supported only in .net 4.5 and higher.
bool pause = true;
void async foo()
{
//some code
while (pause)
{
await Task.Delay(100);
}
//some code
}

C# Timer or Thread.Sleep

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

Categories

Resources