唤醒C#中的线程
本文关键字:线程 唤醒 | 更新日期: 2023-09-27 18:10:42
我正在寻找一种简单的方法来让线程进入睡眠状态并唤醒它。线程在后台以无限循环运行,有时会做一些工作,有时只是贯穿始终。我发现Sleep((没有对应的Wait((,用Interrupt((唤醒线程会导致异常。显然,睡觉的线是不应该被打扰的
既然我知道作品什么时候出现,那么告诉线程似乎是个好主意,而不是让它一遍又一遍地检查。
如何让一个线程进入"较轻的睡眠",以便能够每秒单独醒来或根据其他线程的命令醒来?
//Thread to put to sleep and wake (thread1)
while (true)
{
if (thereIsWork)
{ DoWork(); }
//put thread to sleep in a way that other threads can wake it, and it wakes alone after some time (eg. 1000 ms)
// Thread.Sleep(1000); //nice, but not working as desired
}
-
//Other thread:
thereIsWork = true;
//thread1.Wake(); //Not existing
您可以为此使用AutoResetEvent
-只需调用Set()
来表示需要完成的工作,并让线程等待使用WaitOne()
调用它。
这意味着以这种方式进行通信的线程共享同一个AutoResetEvent
实例——您可以将其作为执行实际工作的线程的依赖项传入。
线程不应该是Sleep()
,它应该在AutoResetEvent
或ManualResetEvent
上调用WaitOne()
,直到其他线程在同一resetevent对象上调用Set()
。
使用具有Monitor Pulse and Wait:的阻塞队列怎么样
class BlockingQueue<T>
{
private Queue<T> _queue = new Queue<T>();
public void Enqueue(T data)
{
if (data == null) throw new ArgumentNullException("data");
lock (_queue)
{
_queue.Enqueue(data);
Monitor.Pulse(_queue);
}
}
public T Dequeue()
{
lock (_queue)
{
while (_queue.Count == 0) Monitor.Wait(_queue);
return _queue.Dequeue();
}
}
}
然后线程1变成
BlockingQueue<Action> _workQueue = new BlockingQueue<Action>();
while (true)
{
var workItem = _workQueue.Dequeue();
workItem();
}
另一个线程:
_workQueue.Enqueue(DoWork);
注意:如果您使用的是使用Add和Take而不是Enqueue和Dequeue的.Net 4 BlockingCollection,那么您可能应该使用内置类型。
编辑:好的。如果你想要非常简单的。。。
//Thread to put to sleep and wake (thread1)
while (true)
{
lock(_lock)
{
while (!thereIsWork) Monitor.Wait(_lock);
DoWork();
}
//put thread to sleep in a way that other threads can wake it, and it wakes alone after some time (eg. 1000 ms)
// Thread.Sleep(1000); //nice, but not working as desired
}
和
//Other thread:
lock(_lock)
{
thereIsWork = true;
//thread1.Wake(); //Not existing
Monitor.Pulse(_lock);
}
我不是线程专家,但也许EventWaitHandle正是您想要的。检查此链接