Is there a way to Interupt a sleeping thread? If I have code similar to this.
while(true){
if(DateTime.Now.Subtract(_lastExecuteTime).TotalHours > 1){
DoWork();
_lastExecuteTime = DateTime.Now();
continue;
}
Thread.Sleep(10000) //Sleep 10 seconds
if(somethingIndicatingQuit){
break;
}
}
I'm wanting to execute DoWork() every hour. So, I'd like to sleep a little longer then 10 seconds. Say check every 10 minutes or so. However, if set my sleep to 10 minutes, and I want to kill this background task, I have to wait for the sleep to resume.
My actual code is using a Threading.ManualResetEvent to shut down the background work, but my issue is with the ThreadSleep code. I can post more code if necessary.
OK, I'm going to add a bit more complete code here as I think it will answer some of the questions.
private readonly ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
private readonly ManualResetEvent _pauseEvent = new ManualResetEvent(true);
private Thread _backGroundWorkerThread;
//This starts our work
public void Start() {
_backGroundWorkerThread = new Thread(ExecuteWorker) {IsBackground = true, Name = WorkerName + "_Thread"};
_shutdownEvent.Reset();
_backGroundWorkerThread.Start();
}
internal void Stop() {
//Signal the shutdown event
_shutdownEvent.Set();
//Make sure to resume any paused threads
_pauseEvent.Set();
//Wait for the thread to exit
_backGroundWorkerThread.Join();
}
private void ExecuteWorker() {
while (true) {
_pauseEvent.WaitOne(Timeout.Infinite);
//This kills our process
if (_shutdownEvent.WaitOne(0)) {
break;
}
if (!_worker.IsReadyToExecute) {
//sleep 5 seconds before checking again. If we go any longer we keep our service from shutting down when it needs to.
Thread.Sleep(5000);
continue;
}
DoWork();
}
}
My problem is here,
_backGroundWorkerThread.Join();
This waits for the Thread.Sleep within the ExecuteWorker() that is running in my background thread.
Instead of using Thread.Sleep
, you can use Monitor.Wait
with a timeout - and then you can use Monitor.Pulse
from a different thread to wake it up.
Don't forget you'll need to lock on the monitor before calling either Wait
or Pulse
:
// In the background thread
lock (monitor)
{
// If we've already been told to quit, we don't want to sleep!
if (somethingIndicatingQuit)
{
break;
}
Monitor.Wait(monitor, TimeSpan.FromSeconds(10));
if (somethingIndicatingQuit)
{
break;
}
}
// To wake it up...
lock (monitor)
{
somethingIndicatingQuit = true;
Monitor.Pulse(monitor);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With