Jef*_*ddy 12 c# multithreading
有没有办法让睡眠线程中断?如果我有类似的代码.
while(true){
if(DateTime.Now.Subtract(_lastExecuteTime).TotalHours > 1){
DoWork();
_lastExecuteTime = DateTime.Now();
continue;
}
Thread.Sleep(10000) //Sleep 10 seconds
if(somethingIndicatingQuit){
break;
}
}
Run Code Online (Sandbox Code Playgroud)
我想每小时执行一次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();
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题在这里,
_backGroundWorkerThread.Join();
Run Code Online (Sandbox Code Playgroud)
这等待在我的后台线程中运行的ExecuteWorker()中的Thread.Sleep.
Jon*_*eet 35
Thread.Sleep您可以使用Monitor.Wait超时 - 而不是使用- 然后您可以使用Monitor.Pulse其他线程将其唤醒.
不要忘记在调用之前你需要锁定显示器Wait或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);
}
Run Code Online (Sandbox Code Playgroud)
Bri*_*eon 15
而不是Thread.Sleep使用ManualResetEvent.WaitOne.
while (true) {
if(DateTime.Now.Subtract(_lastExecuteTime).TotalHours > 1) {
DoWork();
_lastExecuteTime = DateTime.Now();
continue;
}
if (terminate.WaitOne(10000)) {
break;
}
}
Run Code Online (Sandbox Code Playgroud)
哪里terminate是一个ManualResetEvent1,你可以Set请求循环的终止.
更新:
我刚刚注意到你说你已经在使用ManualResetEvent终止后台工作(我假设它已经存在DoWork).你有什么理由不能使用相同的MRE吗?如果那是不可能的,那么使用不同的问题当然不应该是一个问题.
更新2:
是啊,所以不是Thread.Sleep(5000)在ExecuteWorker做_shutdownEvent.WaitOne(5000)代替.它看起来如下.
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.
_shutdownEvent.WaitOne(5000);
continue;
}
DoWork();
}
}
Run Code Online (Sandbox Code Playgroud)
1ManualResetEventSlim .NET 4.0中还有一个类.