[英]Waking a thread in C#
I am looking for a simple way to put a thread to sleep and to wake it. 我正在寻找一种使线程进入睡眠状态并将其唤醒的简单方法。 The thread runs in background in an infinite loop and sometimes does some work, sometimes just runs through.
该线程在无限循环中在后台运行,有时会执行一些工作,有时会一直运行。 I have found out that there is no corresponding Wait() to the Sleep() and waking a thread with Interrupt() causes an exception.
我发现没有与Sleep()相对应的Wait(),并且使用Interrupt()唤醒线程会导致异常。 Apparently a sleeping thread is not meant to be disturbed.
显然,睡眠线程并不意味着被打扰。
Since I know when the work appears it seems a good idea to tell the thread, instead of having it check over and over again. 因为我知道工作何时出现,所以告诉线程似乎是个好主意,而不是一遍又一遍地检查它。
How can a thread be put to a 'lighter sleep' to be able to wake up alone each second or at a command from other thread? 如何将线程置于“较轻的睡眠”状态,以便能够每秒单独唤醒或在其他线程的命令下唤醒?
//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
线程不应进入Sleep()
,而应在AutoResetEvent
或ManualResetEvent
上调用WaitOne()
,直到其他线程在同一resetevent对象上调用Set()
为止。
You can use an AutoResetEvent
for this - just call Set()
to signal work needs to be done and have your thread wait for it to be called using WaitOne()
. 您可以为此使用
AutoResetEvent
只需调用Set()
即可表明需要完成工作,并让线程等待使用WaitOne()
它。
This means the threads that are communicating this way share the same AutoResetEvent
instance - you can pass it in as a dependency for the thread that does the actual work. 这意味着以这种方式进行通信的线程共享相同的
AutoResetEvent
实例-您可以将其作为执行实际工作的线程的依赖项传递。
How about using a blocking queue, with Monitor Pulse and Wait: 如何通过Monitor Pulse和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();
}
}
}
Then thread 1 becomes 然后线程1变成
BlockingQueue<Action> _workQueue = new BlockingQueue<Action>();
while (true)
{
var workItem = _workQueue.Dequeue();
workItem();
}
And the other thread: 而另一个线程:
_workQueue.Enqueue(DoWork);
NB: you should probably use the built in type if you're using .Net 4 BlockingCollection using Add and Take instead of Enqueue and Dequeue. 注意:如果您使用的是.Net 4 BlockingCollection ,而不是Enqueue和Dequeue,则应使用内置类型。
Edit: Ok. 编辑:好的。 If you want it really simple...
如果您真的想简单...
//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
}
and 和
//Other thread:
lock(_lock)
{
thereIsWork = true;
//thread1.Wake(); //Not existing
Monitor.Pulse(_lock);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.