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.SleepuseManualResetEvent.WaitOne.Where
terminateis aManualResetEvent1 that you canSetto request termination of the loop.Update:
I just noticed that you said you are already using
ManualResetEventto terminate the background work (I am assuming that is inDoWork). Is there any reason why you cannot use the same MRE? If that is not possible there certainly should not be an issue using a different one.Update 2:
Yeah, so instead of
Thread.Sleep(5000)inExecuteWorkerdo_shutdownEvent.WaitOne(5000)instead. It would look like the following.1There is also a
ManualResetEventSlimclass in .NET 4.0.