We have a Win Services with need process a lot of Threads simultaneously and, each thread after complete, need hang-on for while before starting again (the time to hang on is on database configuration).
Everything is fine but in certain odd production environments some Threads has been sleeping for eternity with no occurrence of any kind of errors (Local log and Windows Events). The state of Thread is always in "WaitSleepJoin". The only way to get back is restarting the Services.
So, I did some change in our code:
Thread.Sleep(waitTime);
To:
protected void WaitTime(int millesecs)
{
var dateStop = DateTime.Now.AddMilliseconds(millesecs);
while (DateTime.Now < dateStop)
{
//Hang on
}
}
There is any way better than this??
Use events and set the timeout to be your interval. This has the advantage of providing an option of a clean shutdown of the thread by setting the event.
You should not write the code the second way as the thread Wil be taking too much CPU. Your problem is probably not caused by the sleep.
Related
There are 5 threads running in an infinite loop.
2 of them will send messages when queue is not empty.
4 of them will keep sending heartbeat within 5 minutes.
1 of them is to request data from another source.
When it utilizes 100% of the CPU, I can not use any other applications in the window. The whole window becomes very slow.
EDIT: can sleep be put after WaitOne?
if(autoEvent.WaitOne())
{
}
else
{
}
Thread.Sleep(100);
Can sleep be put after subscriber.Recv() which is ZeroMQ ?
all threads i put a sleep if no Recv(), however there is one thread i do not dare to put a sleep in realtime datafeed thread which has only client.Send, will just one thread cause 100% ?
Q: How to make a program not utilize 100% CPU?
A: Don't create a busy loop!!!!
Blocking is Good. There are lots of ways to accomplish "block until there's something to do". Including using an alarm signal or timer (poor, but a definite improvement), doing a socket read with a timeout (if you happen to be notified with a network socket) or using a Windows Event object with a timeout.
Failing all else, you can always use a "Sleep()". I would discourage using "Sleep" if you can avoid it - there are almost always much better design strategies. But it will keep you from a 100% CPU busy loop ;)
=======================================
Addendum: you posted some code (thank you!)
You're using xxx.WaitOne().
Just use WaitOne() (a blocking call), with a timeout. This is an IDEAL solution: no busy loop, no "Sleep" required!
http://msdn.microsoft.com/en-us/library/aa332441%28v=vs.71%29.aspx
Put System.Threading.Thread.Sleep(100) (100 milliseconds sleep = time for system to do something else) in your infinite loops.
For the threads that send messages, when the queue is emtpy, use a ResetEvent
DeliverMessageThread_DoWork
{
while(true)
{
if(GetNextMessage() == null)
MyAutoResetEvent.WaitOne(); // The thread will suspend here until the ARE is signalled
else
{
DeliverMessage();
Thread.Sleep(10); // Give something else a chance to do something
}
}
}
MessageGenerator_NewMessageArrived(object sender, EventArgs e)
{
MyAutoResetEvent.Set(); // If the deliver message thread is suspended, it will carry on now until there are no more messages to send
}
This way, you won't have 2 threads chewing up all of the CPU cycles all of the time
Sorry for the lengthy post, I just want to illustrate my situation as best as possible. Read the items in bold and check the code if you want the quick gist of the issue.
I use ClickOnce to deploy a C# application, and have opted to have my application check for updates manually using the ApplicationDeployment Class rather than letting it do the update checking for me.
The program is a specialized network scanner that searches for network devices made by the company I work for. Once the main window is loaded, a prompt is displayed asking if the user would like to scan the network. If they say Yes, a scan begins which can take a minute or two to complete depending on their network settings; otherwise it just waits for the user to do some action.
One of the last things I do in Form_Load is create a new thread that checks for updates. This had all been working fine for several months through about 12 releases and has suddenly stopped working. I didn't change the update code at all, nor change the sequence of what happens when the app starts.
In staring at the code, I think I see why it is not working correctly and wanted to confirm if what I think is correct. If it is, it begs the question as to why it DID work before - but I'm not too concerned with that either.
Consider the following code:
frmMain.cs
private void Form1_Load(object sender, EventArgs e)
{
// set up ui, load settings etc
Thread t = new Thread(new ParameterizedThreadStart(StartUpdateThread));
t.Start(this);
}
private void StartUpdateThread(object param)
{
IWin32Window owner = param as IWin32Window;
frmAppUpdater.CheckForUpdate(owner);
}
frmAppUpdater.cs
public static void CheckForUpdate(IWin32Window owner)
{
if (ApplicationDeployment.IsNetworkDeployed) {
Console.WriteLine("Going to check for application updates.");
parentWindow = owner;
ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment;
ad.CheckForUpdateCompleted += new CheckForUpdateCompletedEventHandler(ad_CheckForUpdateCompleted);
ad.CheckForUpdateProgressChanged += new DeploymentProgressChangedEventHandler(ad_CheckForUpdateProgressChanged);
ad.CheckForUpdateAsync();
// CAN/WILL THE THREAD CREATED IN FORM1_LOAD BE TERMINATED HERE???
}
}
When the CheckForUpdateAsync() callback completes, if no update is available the method call simply returns; if an update IS available, I use a loop to block until 2 things occur: The user has dismissed the "Would you like to scan prompt" AND no scan is currently running.
The loop looks like this, which takes place in ad_CheckForUpdateCompleted:
while (AppGlobals.ScanInProgress || AppGlobals.ScanPromptVisible) {
System.Threading.Thread.Sleep(5000);
}
I sleep for 5 seconds because I figured this was happening in a separate thread and it has seemed to work well for a while.
My main question about the above code is:
When ad.CheckForUpdateAsync(); is called from CheckForUpdate does the thread I created in Form1_Load terminate (or might it terminate)? I suspect it may because the subsequent Async call causes the method to return, and then start another thread?
The only reason I am confused is because this method WAS working for so long without hanging the application and now all of the sudden it hangs and my best effort at debugging revealed that it was that Sleep call blocking the app.
I'd be happy to post the full code for frmAppUpdater.cs if it would be helpful.
When ad.CheckForUpdateAsync(); is called from CheckForUpdate does
the thread I created in Form1_Load terminate (or might it terminate)?
If the CheckForUpdateAsync() call is asynchronous then yes, the thread will terminate, no it won't otherwise.
If you suspect the Sleep to have caused the application hang then these two variables AppGlobals.ScanInProgress and AppGlobals.ScanPromptVisible are probably always set to true! You should start looking at the code that is setting them to true and see what is going on there.
In order to avoid an application hang, you could introduce a variable to avoid sleeping indefinitely:
int nTrials = 0;
while ((AppGlobals.ScanInProgress || AppGlobals.ScanPromptVisible) && (nTrials < 5)) {
System.Threading.Thread.Sleep(5000);
nTrials++;
}
// Check the results and act accordingly
I personally do not like using Sleep for thread synchronization. .NET offers a bunch of classes that are perfect for thread synchronization, WaitHandle being one of them.
See this post at Asynchronous Delegates Vs Thread/ThreadPool?
your form load method seems to be doing synchronous work. you mention that you are using clickonce deployment. Has the binary location changed after the previous release or has permissions on this resource changed. Looks like the work (checkupdates) in the Thread is never finishing and is never handed back to the form.
as an immediate fix, I would change the Thread approach to Delegate - if you use delegate, then this becomes less of a customer issue (the form will respond to end user) but the underlying problem remains.
as the next step, i would go through http://msdn.microsoft.com/en-us/library/ms229001.aspx and do the troubleshoot
Can anybody suggest any reasons why a C# timer (created in a code-behind class) would stop without being told to?
My timer starts on page load and then stops when I click a button. I don't need to click the button for it to sometimes stop. IIS is not being restarted to my knowledge and no errors are being thrown either.
This is confusing me quite a bit...
Thanks.
// This gets called on page_load
private void checkTimer()
{
if (!parentTimer.Enabled) // If parent timer is not enabled then it is probably the start of a new day (after a night time server backup which kills timers)
{
parentTimer.Interval = 60000; // One minute
parentTimer.Elapsed += new ElapsedEventHandler(parentTimer_Elapsed); // Define what happens when elapsed
parentTimer.AutoReset = true; // Set timer to repeat
parentTimer.Enabled = true; // Start the timer
}
}
protected void btnCancel_Click(object sender, System.EventArgs e)
{
parentTimer.Stop();
...etc...
}
Note: I do not change ParentTimer at all in its elapsed method.
Basically ParentTimer governs a list of ChildTimers. If ParentTimer elapses it checks if one or more of the ChildTimers have elapsed too, if so, there is an event, if not then it resets the ChildTimer and carries on.
My suspicion is it's because the worker process for the page is stopping at the end of the request.
You could try increasing the request time out, but a better question is Can you explain why you're trying to do this ? What is the problem you're trying to solve ?
Remember, that regardless of all the fluff that ASP.Net puts around your code to make you feel comfortable (session state, viewstate etc), a web request is stateless and should be considered as a distinct pass of logic, it's not like a windows application where a background thread of code in your void Main(...) function is constantly running.
A timer is tied to the thread that created it and in the case of ASP.net the thread that handles each page request issued by a given user will change frequently due to the use of worker threads and the thread pool.
Using a timer at page-level simply won't work; you need to be tracking the state at Session-level (tied to the particular user) as your starting point.
In fact, I just wouldn't use timers at all in a web application, because their execution is simply not guaranteed.
If you're using this to run a background task - consider firing up your own worker thread in Application_Start or something like that. The thread will be terminated when the app pool recycles. You should also look at manually shutting the thread down the application is being shut down too.
Be careful with this, however, this thread can't assume it's always the only one running - due to IIS overlapped recycling, when a new one fires up the old one could still be running in the old AppDomain.
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.