I have a program that starts constantly juggles between 3 separate timers.
The main thread of my application has a while loop which constantly checks if a global variable has been set to true and if it has, it will stop one timer and launch two other ones - one continuously, another to stop it automatically if it isn't commanded to stop for whatever reason.
This while loop has a condition of (1==1) so that it runs forever.
In the task manager (XP) I see that my program is using up 50% of cpu on a more or less idle system.
Is there a way to decrease that number by decreasing the speed of the while loop or something?
Thanks.
Is there a way to decrease that number by decreasing the speed of the while loop or something?
Just stop doing a busy loop. There are better ways of coordinating events between threads. Consider using Monitor.Wait/Pulse, or AutoResetEvent / ManualResetEvent. Basically, the thread that sets the global variable should signal that it's done so. Alternatively, if your main thread wouldn't be doing anything else, why not add a normal C# event so that whenever the variable is changed, the event is raised and the appropriate action can be taken?
Your program performs busy waiting, which is a bad practice. You should change your logic so that instead of looping, you block on some kind of synchronization primitive (also known as wait handle).
Blocking on a wait handle is not an option for the UI thread, so you would have to create three threads in total and implement the scheme like this:
The UI thread does not concern itself at all with what other threads to. No looping, no sleeping, no blocking.
The new "controller" thread would start the existing "worker" thread and then immediately block (e.g. on an event that is not signaled). It will remain in this state, without consuming CPU, until the event is signaled (i.e. the "worker" completes).
The "worker" thread would run its course and then signal the event.
Is there a way to decrease that number by decreasing the speed of the while loop or something?
Yes, you could insert a call to Thread.Sleep(n). With a granularity of ~20 ms.
But the far better option would be using a Waithandle.
Your main thread would Wait on the handle and the end of the timer code would signal it to wake up.
You need to sleep the threat for a given number of ms. Look at the Thread.sleep() function and place it within your while loop.
The easiest way to slow down a loop like this is to just add a System.Threading.Thread.Sleep(100); For every iteration the process will sleep for 100 ms and it will not use 50% cpu anymore.
You can use Threads instead of Timer it costlier than Thread. Or Please check the thread state of your time which stopped before start another. You can improve performance by cutting down your code logic.
Hope this will helps you. :)
While the answers here aren't wrong per-say, They don't really address a lot of issues with doing while(true) loops which is what while(1==1) is.
First of, even if the loop is running the entire time your application is in use, you will want to shit it down at some point, say when the user exits your application, because if you have a thread with a constant loop, even if the user closes the UI window, the process will remain until the thread exits (which is never in a while true loop) or until the user becomes wise and closes it from the task manager.
You COULD solve this by putting a true conditional in the while conditional check that references a accessible property outside the loop.
Example:
private bool RequestExit = false;
private Thread MyLoopThread;
private void MyLoop()
{
while (!RequestExit)
{
//Do stuff!
Sleep(1);
}
}
public void StartLoop()
{
RequestExit = false;
MyLoopThread = new Thread(MyLoop);
MyLoopThread.Start();
}
public void StopLoop()
{
RequestExit = true;
}
That is the bare-bones and doesn't even get into avoiding double launches or double shutdown events.
A much cleaner way would be to set an arbitrary interval that you want to pool at, 10ms or so should do just fine for pretty much any real time event, and trigger an method to fire at that interval.
private Timer DoStuffTimer;
private void DoStuffMethod(object obj = null)
{
//Do stuff!
}
public void StartLoop()
{
DoStuffTimer = new Timer(DoStuffMethod,null,10,10);
}
public void StopLoop()
{
DoStuffTimer.Dispose();
}
Related
I'm writing an application working with a big and ugly 3rd party system via a complicated API.
Sometimes some errors happen in the system, but if we wait for my program to face this errors it can be too late.
So, I use a separate thread to check the system state as following:
while (true)
{
ask_state();
check_state();
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1));
}
It doesn't really matter if I check the system state once in 100 ms or once a minute.
But I have heard that using Thread.Sleep() is a bad practice. Why? And what can I do in this situation?
One reason is that Thread.Sleep() is blocking your code from doing anything else. Recent efforts is to make blocking as least as possible. For example, node.js is a non-blocking language.
Update: I don't know about the infrastructure of Timer class in C#. Maybe it's also blocking.
You can schedule a task to check that third API every 100 ms. This way, during that 100 ms, your program can do other tasks.
Update: This analogy might help. If we compare operating system to a hospital, and compare the threads to nurses in that hospital, the supervisor (programmer) can choose a policy:
Either to ask each nurse (thread) to watch one, and only one patient (a job, a task to be done), even if between each check she waits for an hour (Sleep() method)
To ask each nurse to check each patient, and during the interval till next check, go on and check other patients.
The first model is blocking. It's not scalable. But in the second model, even with few nurses, you might be able to serve many patients.
Because the only way to shut down this thread if it's waiting inside the Sleep is to either a) wait for the Sleep to end, or b) use one of Thread.Abort or Thread.Interrupt.1
If it's a long sleep, then (a) isn't really suitable if you're trying to be responsive. And (b) are pretty obnoxious if the code happens to not actually be inside the Sleep at the time.
It's far better, if you want to be able to interrupt the sleeping behaviour in a suitable fashion, to use a waitable object (such as e.g. a ManualResetEvent) - you might then even be able to place the wait on the waitable object into the while conditional, to make it clear what will cause the thread to exit.
1 I've use shutdown in this instance because it's a very common scenario where cross-thread communication is required. But for any other cross-thread signalling or communication, the same arguments can also apply, and if it's not shutdown then Thread.Abort or Thread.Interrupt are even less suitable.
i would set a timer to whatever ms you want and wait for my check methods to complete, by the way do you want to use an eternal loop or it is not a complete code that you showed up there ?
ok this is a sample of what i'm talking about:
public void myFunction()
{
int startCount = Environment.TickCount;
ask_state();
check_state();
while (true)
{
if (Environment.TickCount - startCount >= 20000) //two seconds
{
break;
}
Application.DoEvents();
}
}
//Now you have an organized function that makes the task you want just call it every
// time interval, again you can use a timer to do that for you
private void timer_Tick(object sender, EventArgs e)
{
myFunction();
}
good luck
The way I was told to make windows services is as followed:
Thread serviceThread = new Thread(new Thread(runProc())
Boolean isRunning = true;
if (_isRunning)
{
serviceThread.Start();
}else
close and log service
void runProc()
{
while(_isRunning)
{
//Service tasks
}
_isRunning = false;
}
This has worked fine for me so far but now I need to make a service that has big breaks in it, up to 2 hours at a time. Also I have started using timers so nothing is being done in the infinite loop other than stopping runProc() running over and over again which I can imagine is bad because threads are being made and remade a lot.
My question is, I have read that it is bad practice to put Thread.Sleep(big number) in that while(_isRunning) infinite loop, is this true? If this is the case, how do I get around the loop running constantly and using loads of resource? There is literally nothing being done in the loop right now, it is all handled in the tickevent of my timer, the only reason I have a loop is to stop runProc ending.
Thanks a lot an sorry if I explain myself badly
Thread.Sleep is bad because it cannot be (easily) interrupted1.
I generally prefer to use a ManualResetEvent or similar:
class abc {
Thread serviceThread = new Thread(new Thread(runProc())
ManualResetEvent abort = new ManualResetEvent(false);
void Start(){
serviceThread.Start();
}
void Stop(){
abort.Set();
serviceThread.Join();
}
void runProc()
{
while(!abort.WaitOne(delay))
{
//Service tasks
}
}
}
Hopefully you get the gist, not a great code sample.
The delay can be as large or small as you want (and can be arbitrarily recomputed during each loop). The WaitOne call will either delay the progress of this thread for delay milliseconds or, if Stop is called, will cause the loop to exit immediately.
1To summarize my position from the comments below - it can only be interrupted by blunt tools like Thread.Abort or Thread.Interrupt which both share the failing (to a greater or lesser extent) that they can also introduce their associated exceptions at various other places in your code. If you can guarantee that the thread is actually inside the Thread.Sleep call then the latter may be okay - but if you can make such a guarantee, you can also usually arrange to use a less blunt inter-thread communication mechanism - such as the one I've suggested in this answer.
I've always written services with a main infinite loop, not timers. Inside the loop, I check to see if there's any work to do, if so I do the work, if not I call Thread.Sleep(). That means that as long as there's work to be done, the loop will keep iterating, running as fast as it can. When the queue of work "dries up", it sleeps a little (a few seconds or minutes) while more work becomes available.
That's always worked really well for back-end jobs on a server where there's a constant stream of new work to be done throughout the day (and night). If you have big periods with no work the service will wake many times to check and then go back to sleep. You might like that or not. As long as the check is quick, it shouldn't be an issue. An alternative is to use a scheduled task (or database job) so that you know that work will be completed at specific times throughout the day. That's a better approach in some cases.
I'll be short and to the point. I basically need a way I can take a timer, check when the timer is up and execute something at the end of it, then loop it. For example (this code isn't serious, just example code) :
Timer1.start();
If (timer1.TimeRanOut) {
Timer2.start()
}
Or some other way to pause the timer without the GUI freezing up (I'll be running some things at a fast pace and freezing would get in the way). I'll be making this more complex by looping the entire process, like :
if (Checkbox1.checked == true; )
{
Timer1.start();
Next If (timer1.TimeRanOut) {
Timer2.start()
}
Next If (timer2.TimeRanOut) {
Timer3.start()
}
And so on. Any solutions?
I would suggset working with Tasks. you set up a task to do something (it can just wait for X seconds, than it is a timer) than you set continueWith to assign a new task to run when the first one is finshed.
You can read more about this here:
http://msdn.microsoft.com/en-us/library/dd537612.aspx
And by the way, you really should not run heavy calculations on the UI thread itself.
If you decide to use tasks - that would be fine. Otherwise , you need to create background thread and do the work there.
Edit:
After some clarification from the OP , I will try to explain the basics or working with UI and background threads:
When you run a winforms/WPF application, all of the user interface events are handled in a single thread - the UI thread. it goes over all of the events and processes them.
If long calculation occupy this thread, the UI will become "stuck" and o responsive. see:
UI freezes on heavy calculation
That is why, any long calculations should be done on another thread, in the background.
In the above post's answer there is an example on how to do this.
You could use the System.Threading.Timer. You would then make use of its single shot capability (see Change method). Such you may chain several timers.
The callback of this timer runs on the thread pool so your UI doesn't freeze.
We are using Task in our application. In one class we want to trigger an update that is running on a parallel task. The call looks like:
Maintenance.RecievedMessage += new NotificationHandler(Maintenance_RecievedMessage);
Maintenance.checkLastXML = false;
Maintenance.NeedToUpdateFromCarrier(userId);
SpinWait.SpinUntil(() => isCompleted == true);
return true;
So we hook up an event that is triggered when the Maintenance.NeedToUpdateFromCarrier(userId);
method is done running. The complete method looks like:
private void Maintenance_RecievedMessage(IsCompleted changeargs)
{
isCompleted = true;
}
So we are waiting for the NeedToUpdateFromCarrier method, as soon as it's done it triggers the event that its done, and we catch the event and set the property isComplete to true, and thats when the SpinWait.SpinUntil finnaly is done, and we continue.
Since SpinWait.SpinUntil is very heavy for the CPU, I'm now looking for an alternative solution to this problem.
It is important to understand when spin-waiting is appropriate. There are very few cases where it is. Spin-waiting optimizes thread context switching. Whenever you wait for something, a call like WaitHandle.Wait() will block the thread and yield the processor. The operating system performs a thread context switch when it finds some other thread to perform useful work.
Thread context switches are pretty expensive. There's no exact number because it depends on where the yield-to thread runs, there's extra overhead when that thread runs in another process or protection ring (drivers). It costs between 2000 and 10,000 cycles.
Those are cpu cycles that don't accomplish much. Just overhead that doesn't get real work done. You can optimize your threading code if you know that it always takes less than 20,000 cycles for the wait condition to be met. Just delaying your thread (spinning) will then ensure that the expensive context switching isn't needed. This is not the normal kind of delay like Thread.Sleep(), that yields, it is small loop that burns 100% core. With a few smarts thrown in, like spinning on a machine with only one core will never work well so it yields anyway.
Clearly this will not work well if the wait condition consistently takes more than 20,000 cycles. Now you're on the other end of the wise choice, you do want to yield in those cases. Not just to avoid burning cpu when it doesn't accomplish anything but especially so because yielding makes it now more likely that the wait condition will be met sooner. Because you increase the odds that the thread that sets the wait condition can get enough cpu cycles to finish its job.
There's plenty of evidence that's the case in your code. You explicitly ask code to do something before spinning. And it requires an event handler to signal the completion. Mucho code needs to run. And most convincingly, you are seeing lots of cpu being burned. 1% of load in TaskMgr.exe is about 20 million cpu cycles.
Use a waitable event instead, like AutoResetEvent. Note the structural change required, isCompleted can't be a bool anymore. You call Set() in the completion handler, Wait() to block on it.
You can use a ManualResetEventSlim:
var signal = new ManualResetEventSlim();
Maintenance.RecievedMessage += delegate { signal.Set(); };
Maintenance.checkLastXML = false;
Maintenance.NeedToUpdateFromCarrier(userId);
signal.Wait();
return true;
I have a WinForm drawing a chart from available data.
I programmed it so that every 1 secong the Winform.Timer.Tick event calls a function that:
will dequeue all data available
will add new points on the chart
Right now data to be plotted is really huge and it takes a lot of time to be executed so to update my form. Also Winform.Timer.Tick relies on WM_TIMER , so it executes in the same thread of the Form.
Theses 2 things are making my form very UNresponsive.
What can I do to solve this issue?
I thought the following:
moving away from usage of Winform.Timer and start using a System.Threading.Timer
use the IsInvokeRequired pattern so I will rely on the .NET ThreadPool.
Since I have lots of data, is this a good idea?
I have fear that at some point also the ThreadPool will be too long or too big.
Can you give me your suggestion about my issue?
Thank you very much!
AFG
It is a good idea to move the fetching of the data to a Thread. You can use a BackgroundWorker that gets the data in an endless loop and
use the UpdateProgress event to update the chart. This takes care of the InvokeRequired business
Use a Sleep(remainingTime) inside the loop to get a desired frequency.
It is quite unlikely you'll be ahead by using a background timer. Your chart control almost certainly requires it to be updated from the same thread is was created on. Any kind of control that has a visible appearance does. Which requires you to use Control.BeginInvoke in the Elapsed event handler so that the update code runs on the UI thread. Dequeueing data isn't likely to be expensive, you will have actually have made it slower by invoking. And still not have taken the pressure off the UI thread.
You'll also have a potentially serious throttling problem, the timer will keep on ticking and pump data, even if the UI thread can't keep up. That will eventually crash your program with OOM.
Consider instead to make the code that updates the chart smarter. A chart can only display details of the data if such details are at least a pixel wide. Realistically, it can only display 2000 pixels with useful information. That's not much, updating 2000 data points shouldn't cause any trouble.
I would go with a System.Timers.Timer over a BackgroudWorker in an endless loop.
The BackgroundWorker is executed from a ThreadPool and is not meant to run for the lifetime of your application.
Motivation for System.Timers.Timer:
Each elapsed event is executed from a ThreadPool, won't hang your UI thread.
Using a combination of locks and enabling/disabling the timer we can get the same frequency as if we did a Thread.Sleep(xxx) in an endless loop.
Cleaner and more obvious as to what you are trying to achieve
Here's my suggestion:
Disabling the timer at the beginning of the method, then re-enabling it again at the end, will cater for the case where the amount of work done in the elapsed event takes longer than the timer interval. This also ensures the timer between updates is consistent. I've added a lock for extra precaution.
I used an anonymous method to update the UI thread, but you can abviously do that however you want, as long as you remember to Invoke, it's also a good idea to check the InvokeRequired property
private readonly object chartUpdatingLock = new object();
private void UpdateChartTimerElapsed(object sender, ElapsedEventArgs e)
{
// Try and get a lock, this will cater for the case where two or more events fire
// in quick succession.
if (Monitor.TryEnter(chartUpdatingLock)
{
this.updateChartTimer.Enabled = false;
try
{
// Dequeuing and whatever other work here..
// Invoke the UI thread to update the control
this.myChartControl.Invoke(new MethodInvoker(delegate
{
// Do you UI work here
}));
}
finally
{
this.updateChartTimer.Enabled = true;
Monitor.Exit(chartUpdatingLock);
}
}
}