中断睡眠线程 [英] Interrupt a sleeping Thread

查看:167
本文介绍了中断睡眠线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法来Interupt一个沉睡的线程?如果我有类似下面的代码。

 ,而(真){
如果(DateTime.Now.Subtract(_lastExecuteTime ).TotalHours→1){
DoWork的();
_lastExecuteTime = DateTime.Now();
继续;
}
Thread.sleep代码(10000)//睡眠10秒
如果(somethingIndicatingQuit){
中断;
}

}



我想执行的DoWork () 每隔一小时。所以,我想多睡一会儿,然后10秒。说检查每10分钟左右。但是,如果把我的睡眠10分钟,我要杀死这个后台任务,我必须等到休眠恢复。



我的实际代码使用的是Threading.ManualResetEvent关闭后台工作,但我的问题是与ThreadSleep代码。如果需要的话我可以张贴更多的代码。



OK,我要在这里补充一点更完整的代码,我认为它会回答一些问题。

 私人只读的ManualResetEvent _shutdownEvent =新的ManualResetEvent(假); 
私人只读的ManualResetEvent _pauseEvent =新的ManualResetEvent(真);
私人螺纹_backGroundWorkerThread;

//这将开始我们的工作
公共无效启动(){
_backGroundWorkerThread =新主题(ExecuteWorker){=的IsBackground真,名称= WorkerName +_Thread};
_shutdownEvent.Reset();
_backGroundWorkerThread.Start();
}
内部空隙停止(){
//信号关闭事件
_shutdownEvent.Set();

//确保恢复所有暂停的线程
_pauseEvent.Set();

//等待线程退出
_backGroundWorkerThread.Join();

}

私人无效ExecuteWorker(){
,而(真){
_pauseEvent.WaitOne(Timeout.Infinite);

//这杀死了我们的过程
如果(_shutdownEvent.WaitOne(0)){
中断;
}

如果(!_worker.IsReadyToExecute){
//再睡觉前检查5秒。如果我们再保持我们从关闭时,它需要的服务。
Thread.sleep代码(5000);
继续;
}
的DoWork();

}
}



我的问题就在这里,

  _backGroundWorkerThread.Join(); 

这等待是我的后台线程中运行ExecuteWorker()内Thread.sleep代码。


解决方案

而不是使用 Thread.sleep代码,您可以使用<$的C $ C> Monitor.Wait 一个超时 - 然后你可以使用 Monitor.Pulse 从不同的线程来唤醒它

不要忘了你需要调用之前在监视器上锁定为等待脉冲

  //在后台线程
锁(监视器)
{
//如果我们已经被告知要退出,我们不想睡觉!
如果(somethingIndicatingQuit)
{
中断;
}
Monitor.Wait(显示器,TimeSpan.FromSeconds(10));
如果(somethingIndicatingQuit)
{
中断;
}
}

//要唤醒它...
锁(监视器)
{
somethingIndicatingQuit = TRUE;
Monitor.Pulse(显示器);
}


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);
}

这篇关于中断睡眠线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆