I have a Winform which needs to wait for about 3 - 4 hours. I can't close and somehow reopen the App, as it does few things in background, while it waits.
To achieve the wait - without causing trouble to the UI thread and for other reasons -, I have a BackgroundWorker to which I send how many milliseconds to wait and Call Thread.Sleep(waitTime); in its doWork event. In the backGroundWorker_RunWorkerCompleted event, I do what the program is supposed to do after the wait.
This works fine on the development machine. i.e. the wait ends when it has to end. But on the Test machine, it keeps waiting for longer. It happened two times, first time it waited exactly 1 hour more than specified time and second time it waited more for about 2 Hours and 40 minutes.
Could there be any obvious reason for this to happen or am I missing something?
The dev machine is Win XP and Test machine is Win 7.
I propose to use ManualResetEvent instead:
http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent.aspx
ManualResetEvent mre = new ManualResetEvent(false);
mre.WaitOne(waitTime);
...
//your background worker process
mre.Set();
As a bonus you will have an ability to interrupt this sleep quicker.
Have a look at this article which explains the reason:
Thread.Sleep(n) means block the current thread for at least the number
of timeslices (or thread quantums) that can occur within n
milliseconds. The length of a timeslice is different on different
versions/types of Windows and different processors and generally
ranges from 15 to 30 milliseconds. This means the thread is almost
guaranteed to block for more than n milliseconds. The likelihood that
your thread will re-awaken exactly after n milliseconds is about as
impossible as impossible can be. So, Thread.Sleep is pointless for
timing.
By the way it also explains why not to use Thread.Sleep ;)
I agree to the other recommendations to use a Timer instead of the Thread.Sleep.
In my humble opinion, the difference in wait time cannot solely be explained by the information that you have given us. I would really think that the cause of the difference lies within the moment of starting the sleep. So the actual Thread.sleep(waitTime); call. Are you sure that the sleep is called at the moment you think it is?
And, as suggested by the comment, if you really need to wait for this long; consider using a Timer to start the events needed. Or even scheduling of some sort, within your application. Of course, this depends on your actual implementation and thus can be easier said than done. But it 'feels' silly, letting a BackgroundWorker sleep for so long.
PREFIX: This requires .NET 4 or newer
Consider making your function async and simply doing:
await Task.Delay(waitTime);
Alternately, if you can't make your function async (or don't want to) you could also do:
Task.Delay(waitTime).Wait();
This is a one-line solution and anyone with a copy of Reflector can verify that Task.Delay uses a timer internally.
Related
Right now, I'm reading outside application's memory in a new thread with a infinte loop
public void ReadMemory()
{
//read memory
Thread.Sleep(10);
}
Unfortunately, with even sleep of 1 ms, I can get 60-100 loops during 1 minute. Without any sleep, it's 1000-1500/sec loops but it takes much CPU. I can't believe there's nothing I can do with that so Im asking you here :P. CPU usage might be a problem because I'd like to add few more background-working functions in a different threads(or smth else)
is there anything that doesn't decrease ammount of loops like that with a pause of 10 ms?
Don't worry about CPU usage. It's a nonsensical concept.
There's no such thing as "code that runs a little bit", or "running code slowly to only consume 25% CPU".
At the lowest level, it's a binary thing: your code either runs, consuming 100% of the core it runs on, or it doesn't, in which case it uses 0% CPU.
The CPU usage that the OS shows you is a running average.
So the question you need to ask is not "how do I run my code without using so much CPU", but the much simpler "does my code run when it shouldn't be running?" If you want your code to run, then it will, temporarily, at least, use 100% CPU, and there's nothing wrong with that.
It's not really clear what role the Sleep() call plays in your application.
What are you waiting for? Do you just want a few milliseconds to pass between each iteration? Or are you waiting for some specific event to occur?
In any case, when you call Sleep(10), you are not suspending your thread for 10 milliseconds. You are suspending it for at least 10 milliseconds. You're telling the OS to put the thread into a sleep queue now, and once 10 ms have passed, the thread should be considered eligible to execute again. But that still depends on the OS getting around to scheduling your thread, which might take another 10ms (or more, or less, depending on a variety of factors)
On Windows, Sleep(0) is a special case, which you could experiment with. Instead of actually suspending your thread, it simply tells the OS that the thread is done with its current timeslice, allowing other threads/processes to execute, but without putting your thread to sleep: it's still eligible to be scheduled the next time a context switch occurs.
So if the goal is simply to ensure that other threads/processes get a chance to run, calling Sleep(0) might be a way to do it.
Another way is just to ignore the issue, and trust that the OS knows how to schedule processes (that is a pretty safe assumption. Don't worry about this unless you've actually seen that your other background processes are being starved. They most likely won't be).
And finally, of course, you can set thread and process priority, hinting to the OS at which threads it should prefer to schedule. If you give this thread a low priority, it will only be scheduled when no higher-prioritized thread is available, ensuring you won't starve out other threads.
Threads are designed to consume as much CPU time as they can, unless other threads need that CPU time. If you're just trying to release the thread so that the CPU can do other tasks, don't. Windows will automatically allocate horsepower to any other threads, as needed.
Rather than sleeping every iteration, what if you only do it occasionally.
Something like :
public class Reader
{
private static int count= 0;
public void ReadMemory()
{
//read memory
// Sleep every 501 iterations
if (Reader.count++ == 500)
{
Thread.Sleep(1);
Reader.count = 0;
}
}
}
If you are running at about 1000 iterations a second and it takes 1 second to perform the switch then this will mean you will be running at full power for half-a-second, then throttle back for a second and then back to full power which will average out at 333 iterations per second.
Obviously you can try experimenting with values other than 500.
I'm new in C# and I'm using System.Threading.
I have this code:
UISystem.SetScene(Scene_Menu);
Thread.Sleep (9000);
p.Text="HELLO";
Thread.Sleep(9000);
p.Text="WORLD";
It delays 18 seconds, but the p.Text="HELLO" doesn't show between the sleep functions. What's the problem with my code?
Thanks.
Timers don't work since I can't edit p from a separate thread.
Application.DoEvents() is a Windows Forms function, I'm building an application in PS Vita.
You have discovered why you should never use Thread.Sleep. It is useful for only two things. (1) Writing test cases that need to simulate a thread being busy for a certain number of seconds, and (2) Sleeping for zero milliseconds tells the operating system "I cede the rest of my time slice to another process if there exists one that wants it"; it's a politeness thing.
You should never use thread.Sleep to introduce a delay as you are doing for exactly the reason you have discovered. You are setting a property, but setting a property does not cause the operating system to repaint the screen. Consider if it did; you might have a thousand property sets in a method, and you would have to repaint the screen after all of them, which would look ugly and be very slow.
Instead what happens is the property is set and the object makes a note to the operating system that says when this thread is available to handle operating system messages again, please repaint me. Your program is, instead of telling the operating system "I'm done, go ahead and see if there are any message for me" that instead you want the thread to do nothing for nine seconds.
Now, you can tell the program to check for messages by calling DoEvents but using DoEvents is also a bad idea and you should not do it. Doing so essentially causes your program to exhibit symptoms of Attention Deficit Disorder; you have not finished the current job and you are looking to see if there are new jobs to do without removing the old jobs from the call stack! Suppose those new jobs in turn get interrupted, and so on, and so on. The stack grows without bound, which is very bad. DoEvents is a "worst practice", just like sleeping a thread. You can get away with it in small simple programs but it leads to big trouble when the program becomes complex.
Moreover: yes, DoEvents will paint your control, but that is all it will do. For the next nine seconds, the application will appear to the user to be completely hung. That is a very bad user experience.
The right thing to do if you want to introduce a delay is to asynchronously wait. In C# 4 and earlier the standard way to do that is to create a timer, and when the timer ticks, do the next thing.
Now, you say that you cannot use a timer because you need to access the control from the UI thread. That's fine. The timer's tick event handler will run on the UI thread, not on a separate thread. You can safely use a timer.
In C# 5, the right thing to do is to use the new await keyword to introduce an asynchronous wait. That is, a wait that does other stuff while it is waiting, instead of going to sleep while it is waiting. In C# 5 you would write your code as:
UISystem.SetScene(Scene_Menu);
await Task.Delay (9000);
p.Text="HELLO";
await Task.Delay(9000);
p.Text="WORLD";
C# 5 is at present in beta; for details on this new feature see:
http://msdn.microsoft.com/en-us/async
For a gentle introduction to async and an explanation of why DoEvents is bad news, see my MSDN magazine article:
http://msdn.microsoft.com/en-us/magazine/hh456401.aspx
I need prety simple thing
while (true) {
DoJob();
// wait 1 ms
}
Should I just use Thread.Sleep(1)?
I'm not sure about using Timer because it seems overhead of Timer itself is a little bit more than 1 ms.
Update: I need this delay to be sure that I received the most recent information from network, it's trading software. I need to do something and then I have to wait 1 ms to see what happens. I can wait 1.5 ms, but not 3 ms, that would be too much. It's ok to wait rarely 5 or 10 ms, but in general it should be ~1 ms
Edit -- corrected "most resolution you will get from sleep to about 20 ms, instead of 100 ms
About the most resolution that you will get out of sleep is 100 milliseconds, even if you pass Sleep(1).
For what it's worth, a timer may be more efficient for this -- especially if you have more than 1 thread sleeping (System.Threading.Timer will will use as few threads as it needs to if you allocate multiple timers, they will share a timing thread) (this from Joe Duffy's Concurrent Programming book)
But more importantly, what are you trying to do? If you are polling -- need to wait for something to happen, you may be able to use a more efficient means of doing it. If you just need to fire off a task every so often, A timer is probably going to be your best bet.
If you are only want to stop for a millisecond, may I ask why? Are you just trying to make sure that your thread yields to other processes?
There may be an alternative way to do this. Windows has a high resolution timer. You can read about it here: "How to: Use the high resolution timer"
I don't think that this works like a regular timer -- it doesn't fire off events, you just use it to measure how much time has passed with high precision. However, you could loop on it, and execute code when a Millisecond passes (you will be consuming CPU the whole time). Also, I agree with Henk's comments that Windows is not a realtime O/S -- you never know when the O/S will suspend your thread.
I have queue of tasks for the ThreadPool, and each task has a tendency to froze locking up all the resources it is using. And these cant be released unless the service is restarted.
Is there a way in the ThreadPool to know that its thread is already frozen? I have an idea of using a time out, (though i still dont know how to write it), but i think its not safe because the length of time for processing is not uniform.
I don't want to be too presumptuous here, but a good dose of actually finding out what the problem is and fixing it is the best course with deadlocks.
Run a debug version of your service and wait until it deadlocks. It will stay deadlocked as this is a wonderful property of deadlocks.
Attach the Visual Studio debugger to the service.
"Break All".
Bring up your threads windows, and start spelunking...
Unless you have a sound architecture\design\reason to choose victims in the first place, don't do it - period. It's pretty much a recipe for disaster to arbitrarily bash threads over the head when they're in the middle of something.
(This is perhaps a bit lowlevel, but at least it is a simple solution. As I don't know C#'s API, this is a general solution for any language using thread-pools.)
Insert a watchdog task after each real task that updates a time value with the current time. If this value is larger than you max task run time (say 10 seconds), you know that something is stuck.
Instead of setting a time and polling it, you could continuously set and reset some timers 10 secs into the future. When it triggers, a task has hung.
The best way is probably to wrap each task in a "Watchdog" Task class that does this automatically. That way, upon completion, you'd clear the timer, and you could also set a per-task timeout, which might be useful.
You obviously need one time/timer object for each thread in the threadpool, but that's solvable via thread-local variables.
Note that this solution does not require you to modify your tasks' code. It only modifies the code putting tasks into the pool.
One way is to use a watchdog timer (a solution usually done in hardware but applicable to software as well).
Have each thread set a thread-specific value to 1 at least once every five seconds (for example).
Then your watchdog timer wakes every ten seconds (again, this is an example figure only) and checks to ensure that all the values are 1. If they're not 1, then a thread has locked up.
The watchdog timer then sets them all to 0 and goes back to sleep for the next cycle.
Providing your worker threads are written in such a way so that they will be able to set the values in a timely manner under non-frozen conditions, this scheme will work okay.
The first thread that locks up will not set its value to 1, and this will be detected by the watchdog timer on the next cycle.
However, a better solution is to find out why the threads are freezing in the first place and fix that.
I am not using Thread so can't use thread.sleep() method.. Its part of my program where I need to introduce some delay .. Not precisely 1mSec but almost that ..
which is the standard method that is known to be so??
You are always using a thread. Every application has at least one thread, so Thread.Sleep will work fine.
I am not using Thread so can't use thread.sleep() method
Not sure you you say that -- you can use Thread.Sleep anywhere you like.
Just so you know, a 1msec sleep isn't guaranteed be exactly 1msec, in fact it's very improbable due to it being such a small time. The thread.sleep(x) states x as a minimum sleep time, if you wan't a much more exact sleep you might want to look into win32 multimedia timers: http://msdn.microsoft.com/en-us/library/dd742877.aspx
Don't sleep 1msec. It will not be accurate at all. Read for instance this article or this
Thread.sleep will always suspend the current thread. Keep in mind that it's not a good idea to use Sleep on a GUI thread (if your app is a winform app).
If you are just trying to provide an opportunity for thread switching, then use Thread.Sleep(0). (This is equivalent to Thread.Yield() in Java.)
Edit: actually seems like they've added Thread.Yield() in .NET 4.