【发布时间】:2011-09-16 17:57:47
【问题描述】:
有没有办法中断睡眠线程?如果我有类似的代码。
while(true){
if(DateTime.Now.Subtract(_lastExecuteTime).TotalHours > 1){
DoWork();
_lastExecuteTime = DateTime.Now();
continue;
}
Thread.Sleep(10000) //Sleep 10 seconds
if(somethingIndicatingQuit){
break;
}
}
我想每小时执行一次 DoWork()。所以,我想多睡10秒。说每 10 分钟左右检查一次。但是,如果将我的睡眠设置为 10 分钟,并且我想终止这个后台任务,我必须等待睡眠恢复。
我的实际代码是使用 Threading.ManualResetEvent 来关闭后台工作,但我的问题在于 ThreadSleep 代码。如果需要,我可以发布更多代码。
好的,我将在这里添加更完整的代码,因为我认为它会回答一些问题。
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();
}
}
我的问题来了,
_backGroundWorkerThread.Join();
这将等待在我的后台线程中运行的 ExecuteWorker() 中的 Thread.Sleep。
【问题讨论】:
-
您不使用计时器有什么具体原因吗?您可以将该代码减去循环放在一个方法中,并将其作为每 n 分钟执行一次的 Timer 的回调传递,然后停止任务只需终止 Timer 或将其间隔设置为 Infinite。
-
我已经发布了更多代码。此代码的类是管理无限数量的父类的子类。父控制这些子类的启动、停止、暂停和继续以及它们正在做的工作。需要支持的不是简单的启动和停止问题。
-
这里的
_worker是什么? -
只是一个具有调度逻辑的类的实例。它的方法 IsReadyToExecute 返回一个布尔值。 _worker 与这个问题无关。
标签: c# multithreading