Thread.Sleep...

  • Thread starter Thread starter news.microsoft.com
  • Start date Start date
N

news.microsoft.com

Hi,

Currently I have a thread thats spinning and doing a
Thread.Sleep(someTime).

I was thinking of changing this to Thread.Sleep(Timeout.Infinite); then
when I have actual data in a collection to process in this thread, I was
going to do a _thread.Interrupt(); Would this be a better approach to
spinning a thread on ?
 
news.microsoft.com said:
Currently I have a thread thats spinning and doing a
Thread.Sleep(someTime).

I was thinking of changing this to Thread.Sleep(Timeout.Infinite); then
when I have actual data in a collection to process in this thread, I was
going to do a _thread.Interrupt(); Would this be a better approach to
spinning a thread on ?

A better approach still would be to use Monitor.Wait and Monitor.Pulse.
 
You can use the Q.Sychronized wrapper and not have to use lock(q) blah

The only time u need to use the lock(q) is when you are using IEnumerator as
its intrisincally blah cant spell not thread safe.

So the simpler approach in a code base would be to sleep infinte and then
interrupt that.



Alvin Bruney said:
Jon,
how long you been writing thread code?
 
IF you need to use lock on a colleciton object you use the SynRoot. Why
bother with all that Monitor stuff and lock when you dont need to?


news.microsoft.com said:
You can use the Q.Sychronized wrapper and not have to use lock(q) blah

The only time u need to use the lock(q) is when you are using IEnumerator as
its intrisincally blah cant spell not thread safe.

So the simpler approach in a code base would be to sleep infinte and then
interrupt that.
 
I dont want it to be spinning all the time at 100% CPU, i want it to rest
then once its interrupted, to start to spin a predefined cycle rate using
Sleep(blah) then once its empty, to go infinite again.
Alvin Bruney said:
Jon,
how long you been writing thread code?
 
You're right that the Thread.Interrupt() approach is better than a
Thread.Sleep(someTime) loop. The only thing is that as I'm sure you know,
Thread.Interrupt() causes an exception to be thrown on the specified
thread... not really a problem if you catch it, but from what I read,
throwing/catching exceptions over and over again is a somewhat expensive and
inefficient thing to do.

Perhaps try a more traditional approach: Create an AutoResetEvent object
and have your worker thread call Wait() against that event object. The
thread then goes to Sleep (0% CPU utilization) until the event is "signaled"
by another thread. So when your program determines that there is work to be
done, it signals the event (see AutoResetEvent.Set()) and your worker thread
instantly "wakes up" to do its thing.

David
 
Alvin Bruney said:
how long you been writing thread code?

A fair time - why?

I'm suggesting Monitor.Wait/Pulse because they (along with
Manual/AutoResetEvents) are specifically designed for exactly this kind
of thing.
 
a fair time? what's that 2 days? 2 months? 2 years?
am asking when you started to actually write it, not when you first knew it
existed or heard about it.
 
Alvin Bruney said:
a fair time? what's that 2 days? 2 months? 2 years?

Longer than that.
am asking when you started to actually write it, not when you first knew it
existed or heard about it.

*Started* to write stuff using threads? About 9 years ago, when I first
started writing Java. Started thinking seriously about it and really
examining things carefully? About 4 years ago.

Again I ask: why do you want to know?
 
As some others have pointed out, the best method to use is to wait on an
event to be signalled. A thread that is blocked waiting on an event consumes
0 cpu cycles. Using a spin-wait is the absolute worst way to wait for work
to arrive as it consumes lots of cpu cycles while producing nothing of
value. Using a thread-interrupt is better but not much. In general you
should use synchronization primitives (events, mutexes, semaphores, etc) to
synchronize access to shared resources, and execution control primitives
(suspend/resume/sleep) to control the execution state of a thread. It is
usually extremely rare that user-mode code needs to actually control the
execution state of a thread and very common to need to control the
synchronization of threads to a shared resource.
 
I used the AutoResetEvent.Set to signal the worker thread and
AutoResetEvent.WaitOne() to put it to sleep.

I dont see the need for Monitor.Wait and Monitor.Pulse as the shared item is
already using the synchronised wrapper.

I still have a spin wait so its working on the items at a good pace and not
burning the CPU from other more important threads. Is it possible to
prioritise threads?
 
news.microsoft.com said:
I used the AutoResetEvent.Set to signal the worker thread and
AutoResetEvent.WaitOne() to put it to sleep.

I dont see the need for Monitor.Wait and Monitor.Pulse as the shared item is
already using the synchronised wrapper.

You're certainly only like to need *either* AutoResetEvent *or*
Monitor.Wait/Pulse, but I don't see why using a synchronised wrapper
would knock Monitor.Wait/Pulse out of the equation.
I still have a spin wait so its working on the items at a good pace and not
burning the CPU from other more important threads.

I don't think a spin wait is a particularly good way of doing that
though - why not just sleep briefly? IIRC, the purpose of spin waits is
to wait *without* yielding to another thread, if you have a good reason
to believe that the reason you're unwilling to do more work is about to
be removed, as it were.
Is it possible to prioritise threads?

Sort of - have a look at the Thread.Priority property. Note that it
doesn't have to be honoured.
 
I only spin wait if the .Count is positive. so its processing at a regular
frequency. Its only doing Wait once its empty. Likely this shared
collection will come in bursts.
 
When I said spinwait i meant a Thread.Sleep(Frequency); not per iteration
as in SpinWait(N);

Maybe a bad choice of terminology.
 
AutoResetEvent Just made more sense to me than Monitor.Wait and .Pulse, both
would be doing the same job here so what are the benifits of
Monitor.Wait/Pulse over AutoResetEvent?


news.microsoft.com said:
When I said spinwait i meant a Thread.Sleep(Frequency); not per iteration
as in SpinWait(N);

Maybe a bad choice of terminology.

Jon Skeet said:
You're certainly only like to need *either* AutoResetEvent *or*
Monitor.Wait/Pulse, but I don't see why using a synchronised wrapper
would knock Monitor.Wait/Pulse out of the equation.
and
 
news.microsoft.com said:
When I said spinwait i meant a Thread.Sleep(Frequency); not per iteration
as in SpinWait(N);

Ah, right. A spin wait is very different - it's a way of saying, "Keep
yourself busy, but don't actually do anything useful, just for a little
bit." Thread.Sleep is fine.
AutoResetEvent Just made more sense to me than Monitor.Wait and .Pulse, both
would be doing the same job here so what are the benifits of
Monitor.Wait/Pulse over AutoResetEvent?

I don't know that there are any, other than that Monitor.Wait/Pulse are
less .NET/Windows-specific concepts. They act in slightly different
ways, but I don't know enough detail about what you want to know which
would be better.

I tend to prefer Monitor.Wait/Pulse/PulseAll as they're very similar to
Java's Object.Wait/Notify/NotifyAll. Just personal preference, really.
 
I think most people are familiar with the concept of AutoResetEvents more
than monitor pulse and wait so its even more readable. Both achieve the
same effect as far as I can see except Monitor takes a lock on the object
and autosetevent does not. Its just an event really. Since the item is
already synchronised I was more concerned about taking another lock on that
object with Monitor.Wait/Pulse.
 
news.microsoft.com said:
I think most people are familiar with the concept of AutoResetEvents more
than monitor pulse and wait so its even more readable.

That really depends on their background. If they're Java programmers
they'll be more familiar with monitors and waiting/notifying them. If
they're Win32 programmers they're probably more familiar with
AutoResetEvents.
Both achieve the
same effect as far as I can see except Monitor takes a lock on the object
and autosetevent does not. Its just an event really. Since the item is
already synchronised I was more concerned about taking another lock on that
object with Monitor.Wait/Pulse.

You don't have to use that particular object though - I usually
advocate using a separate object specifically for locking/waiting etc.
The cost of taking out a lock is pretty small, especially when
uncontested.
 
Back
Top