Terminating Thread.Sleep but not thread flow

R

Ray Mitchell

Hello,

I have a thread ABC that starts another thread XYX. Thread XYZ monitors
various things and if there is no work to do it calls Thread.Sleep to sleep
for a minute or so. Occasionally thread ABC needs to get thread XYZ's quick
attention. My first attempt at this was to have thread ABC merely set a
global flag variable that thread XYZ would check at specific points in its
execution, and if it saw that the flag was set it would take the appropriate
action. This worked perfectly unless thread XYZ happened to be sleeping, in
which case it wouldn't see the flag until it awakened. I then changed the
code so that thread ABC would do a threadXYZ.Interrupt, which thread XYZ
would then catch. This solved the sleeping problem put produced another
problem. If thread XYX happened to not be sleeping at the time the
threadXYZ.Interrupt was issued, it would immediately terminate whatever it
was doing with a ThreadInterruptedException. The problem is that I only want
thread XYZ to stop its normal program flow at specific points, that is, at
the points where it checks the global flag, but I want an immediate
termination of its sleep. What is the correct way to achieve this?

Thanks,
Ray
 
R

Ray Mitchell

Peter Duniho said:
[...] The problem is that I only want
thread XYZ to stop its normal program flow at specific points, that is,
at
the points where it checks the global flag, but I want an immediate
termination of its sleep. What is the correct way to achieve this?

As you've found through experimentation, Thread.Sleep() isn't useful for
the purpose you're applying it to. If you only want a thread to yield the
CPU for some specific amount of time, for the express purpose of that
actual delay, then use Thread.Sleep(). Otherwise, don't.

There are a variety of valid approaches to what you're trying to do,
depending on the overall design. Since you haven't described the bigger
picture, it's impossible to provide specific advice. But, you may find
the AutoResetEvent class useful. You can create an instance of that, then
have your thread call the WaitOne() method. Another thread can call Set()
on the AutoResetEvent instance, and the thread waiting at the WaitOne()
method call will then be woken up and continue execution.

You can pass a timeout value to the WaitOne() method and if your thread is
still waiting after that time passes, the method will return anyway. This
allows you to combine the periodic wake-up behavior with the interrupt
wake-up behavior.

That said, you really should try to avoid an implementation where you need
to use the timeout. Whatever your thread is waiting on, it would be much
better if the activity it's waiting on instead could explicitly interrupt
the waiting thread by itself setting the AutoResetEvent instance, or by
using one of the other many asynchronous notification techniques available
in .NET.

Pete

As always Pete, thanks for taking the time for the detailed and informative
explanation. I've implemented AutoResetEvent and it works just like you said
it would. I've apparently got some other issues going on too so you may hear
from me again about this.

Thanks,
Ray
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top