|
devvvy wrote: THUS FAR there isn't ONE SINGLE argument that justify against use of
Thread.Sleep against SCENARIO 2.
Errm. Yes, we have posted arguments against, you're just choosing to ignore them.
As for the reason I show Monitor.Wait is that it is close to the behaviour you're after with your Thread.Sleep, in that it puts the ThreadState into WaitSleepJoin, but it doesn't yield the thread to the OS. This is an important point because you can wake this thread up if you need to. This is the point you seem to be missing. Thread.Sleep - there is no wake up, other than through a Thread.Abort and we've already covered how that makes things unpredicable - if you need to cancel the thread and have it tidy itself up you have to wait for it to wake up.
Also, Dave has a very valid point about the behaviour in STA COM. In this scenario, again, this is a justification that Thread.Sleep should not be used. It is not the appropriate mechanism.
|
|
|
|
|
Pete O'Hanlon wrote:
Errm. Yes, we have posted arguments against, you're just choosing to ignore them. I second that.
He don't have the maturity to understand what people are saying. So no point in discussing further.
|
|
|
|
|
there's no point because you're still confused SCENARIO 2 a simple background thread with a while+Sleep with no UI pump, with SCENARIO 1/3
you ran out of further arguments don't you?
dev
|
|
|
|
|
1. As I pointed out earlier, there's no need to know *exact* when the blocked thread wakes up again.
2. STA COM debug messages -> how's debug messages in debug mode in a thread with a message pump affect me if all i've got is a non-ui baclground thread?
dev
|
|
|
|
|
devvvy wrote: 1. As I pointed out earlier, there's no need to know *exact* when the blocked thread wakes up again.
There is if you're trying to shut down an application. I don't know how many times I can point out the same thing; perhaps with a simple example - you have a service with a thread that needs to clean up before the service can shut down - by having to wait for the thread to finish, you could trigger the "Service could not be stopped, blah blah blah" message. I have seen this happen many times, and it's always been because someone who doesn't know any better has decided that a simple one liner is better then something that behaves cleanly.
If you know what you're doing, and if you're well informed about the pitfalls in Thread.Sleep, and if you've thought through the implications then by all means, use Thread.Sleep. If you can't claim all of these conditions, then look for a safer alternative - one that won't leave your users wanting to hang you by your testicles when you inconvenience them because you couldn't be bothered to type in three lines.
|
|
|
|
|
Pete O'Hanlon wrote: There is if you're trying to shut down an application. I don't know how many times I can point out the same thing; perhaps with a simple example - you have a service with a thread that needs to clean up before the service can shut down - by having to wait for the thread to finish, you could trigger the "Service could not be stopped, blah blah blah" message.
My apologies Pete - this is something we'd run into if we're not careful with SCENARIO 2 if Thread.Sleep(LONGTIME) (where timer/handler would have avoided this). Having consider this, Thread.Sleep even for SCENARIO 2 may likely to cause problem in app exit if not used carefully. I don't think this very important argument has nearly enough visibility in this discussion/other places. Thanks Pete!
Thread.Sleep is Evil after all. (For SCENARIO 1,2,3)
Sample to demo the issue as follows:
<br />
static void Main(string[] args)<br />
{<br />
Thread t = new Thread(new ThreadStart(ThreadFunc));<br />
t.Start();<br />
<br />
Console.WriteLine("Hit any key to exit.");<br />
Console.ReadLine();<br />
<br />
Console.WriteLine("App exiting");<br />
return;<br />
}<br />
<br />
static void ThreadFunc()<br />
{<br />
int i=0;<br />
try<br />
{<br />
while (true)<br />
{<br />
Console.WriteLine(i);<br />
Thread.Sleep(1000 * 10);<br />
i++;<br />
}<br />
}<br />
finally<br />
{<br />
Console.WriteLine("Exiting while loop");<br />
}<br />
return;<br />
dev
|
|
|
|
|
devvvy wrote:
THUS FAR there isn't ONE SINGLE argument that justify against use of Thread.Sleep against SCENARIO 2. As Pete already told, you are ignoring the comments that we made for Scenario2. See my answer.
|
|
|
|
|
i pointed out timer + event handler as an alternative in the first place, but it's more lines of code for no additional benefit than a simple while+Sleep
dev
|
|
|
|
|
I haven't read the article at all, but I'll give you another reason why it's evil. Every once in a while, you can get this little cryptic error message and you've got absolutely no clue as to what it means or why you're getting it:
"The CLR has been unable to transition from COM context #x###### to COM context #x###### for 60 seconds. The thread that owns the destination context/apartment...blah blah blah"
Why does this happen?? Well, you get this mesage onyl when running under the debugger. Usually it's because Thread.Sleep has been called for greater than 60 seconds or there is a long running operation going on on a thread hosting a message pump. STA COM is accomplished through message passing and if those message don't get processed ... kaboom!
|
|
|
|
|
ok, that's if the worker thread has a message pump - if not nothing wrong.
dev
|
|
|
|
|
No, it's not. Do you know how times I've seen Thread.Sleep show up on the UI thread?? LOTS!
|
|
|
|
|
still - there's nothing against SCENARIO 2, if it's not a UI thread or one with a message pump.
Thread.Sleep isn't evil - it's just uncool. It's uncool because most developers tell each other it's uncool to do so.
dev
|
|
|
|
|
OK, it's "uncool" because most people (noobs) use it like they use PictureBox. They use it without knowing it's limitations and without knowing that there are far better alternatives to it.
|
|
|
|
|
it's a simple reliable picture box. if people use it for SCENARIO 1/3 it's just absurb in the first place.
but SCENARIO 2 it's just not much to talk about - the fact there is simply because people wasting each other time trying to complicate otherwise very simple Thread.Sleep
dev
|
|
|
|
|
Oh but Thread.Sleep is not so simple. Using it has vast implications on the functionality of the rest of your app. That's why so many noobs use it and can't figure out why their app doesn't work properly or, as you mentioned, you can't shutdown a service without timing out the Service Manager.
|
|
|
|
|
I saw two arguments against using Thread.Sleep for scenario 2
a. From you: Thread.Sleep screw up message pump IF you do this on UI Thread (But why'd you Thread.Sleep on UI in the first place!)
b. From Pete: Application exit
Both are valid arguments - But I don't think I stumble across these in other places at all. They deserve more visibility I now agree - Thread.Sleep is evil.
(And can be replaced/avoided by one line timer+handler if you wrap it up in one blocking function call)
Thank you!
dev
modified 19-Feb-13 20:29pm.
|
|
|
|
|
There is one case in which I have used it where it is actually useful to slow things down for the user.
The case in point is an update to an application - sometimes the update is so small that all the user would see is a number of dialogues and progress bars flashing on the screen leaving them to wonder if the update has taken place.
So I introduced a four second sleep in order to allow the user to see that something was happening.
It has saved me from having to say "yes the update did take place, it was just very small" - that comfortable warm feeling is very important to the user.
“That which can be asserted without evidence, can be dismissed without evidence.”
― Christopher Hitchens
|
|
|
|
|
Or something like this:
public class Utility
{
private static readonly object SyncLock = new object();
public void WaitForTime(int milliseconds)
{
lock (SyncLock)
{
Monitor.Wait(SyncLock, milliseconds);
}
}
public WakeAllThreads()
{
lock (SyncLock)
{
Monitor.PulseAll(SyncLock);
}
}
}
|
|
|
|
|
Thanks Pete! Much appreciated
I shall now use that method - it would be nice if Microsoft deprecated the sleep method so that people like me were prevented from using it.
“That which can be asserted without evidence, can be dismissed without evidence.”
― Christopher Hitchens
|
|
|
|
|
why the appreciation? It's more code than a simple while loop with a Sleep.
why you want be thankful when there really isn't a justification for it?
M$ probably deprecate Thread.Sleep either because its syntax laywer told him so or simply it isn't "cool"
dev
|
|
|
|
|
devvvy wrote: why the appreciation? It's more code than a simple while loop with a Sleep.
So, you think he has to write this out every time? Chuck it in a library and you're done - a simple
new Utility().WaitForTime(5000);
|
|
|
|
|
Peter - this is nice/good idea. But this detracts the discussion to get to the bottom:
SCENARIO 1/3 is just plain stupid to use Thread.Sleep - so just forget it.
SCENARIO 2 - there's yet one single real justification to establish "Thread.Sleep" is *Evil*
(as i pointed out in very beginning timer+event handler *can* be alternative - but why bother)
dev
|
|
|
|
|
devvvy wrote: But this detracts the discussion to get to the bottom
No it doesn't. It shows alternatives. The reason people are using the term "Evil" (and I think this is the word you're getting hung up on) is because threading isn't easy. It isn't trivial. But Thread.Sleep makes it appear as though it is because it's a convenience to hide the complexity, and sooner or later, this complexity creeps out and rips your face clean off. Subtle bugs creep in and they are hugely difficult to track down because they are timing based, and that timing is not predictable, because Thread.Sleep isn't predictable. The OS can actually do different things depending on what you've done with it.
|
|
|
|
|
Thanks Pete - I saw your argument on application exit.
Now I would conclude Thread.Sleep is evil for all SCENARIO 1,2,3
Big Thank you!
dev
|
|
|
|
|
devvvy wrote: why the appreciation? It's more code than a simple while loop with a Sleep.
why you want be thankful when there really isn't a justification for it?
Because someone, especially as it is a person I don't personally know, went out of their way to offer me help.
In my books that deserves my appreciation
“That which can be asserted without evidence, can be dismissed without evidence.”
― Christopher Hitchens
|
|
|
|