有没有Monitor.Pulse和Monitor.Wait的等价物可以与ReaderWriterLockSlim一起使用
我有一个类,其中封装了对底层队列的多线程访问。要将某物入队,我需要获取一个保护底层队列(以及其他几个对象)的锁,然后添加该项并锁定( Monitor.Pulse )对象,以发出某物被添加到队列的信号。
public void Enqueue(ITask task)
{
lock (mutex)
{
underlying.Enqueue(task);
Monitor.Pulse(mutex);
}
}在队列的另一端,我有一个后台线程,它在消息到达队列时持续处理消息。当队列中没有项目时,它使用Monitor.Wait,以避免不必要的轮询。(我认为这是一个好的设计,但是任何火焰(在合理的范围内)都是受欢迎的,如果它们能帮助我学习的话。)
private void DequeueForProcessing(object state)
{
while (true)
{
ITask task;
lock (mutex)
{
while (underlying.Count == 0)
{
Monitor.Wait(mutex);
}
task = underlying.Dequeue();
}
Process(task);
}
}随着更多的操作被添加到这个类中(需要对受保护的底层锁进行只读访问),有人建议使用ReaderWriterLockSlim。我以前从未使用过这个类,假设它可以提供一些性能优势,我并不反对它,但前提是我可以保持Pulse/Wait设计。
发布于 2010-04-23 06:39:16
在尝试了一下(在接受了Mark的挑战之后(我同意,我的改变并不完全是基本的)),我想出了这个组合:
ReaderWriterLockSlim rwls;
AutoResetEvent are;public void Enqueue(ITask task) {
rwls.EnterWriteLock();
try {
underlying.Enqueue(task);
if (underlying.Count == 1) {
are.Set();
}
} finally {
rwls.ExitWriteLock();
}
}private void DequeueForProcessing(object state) {
while (true) {
ITask task;
rwls.EnterWriteLock();
try {
while (underlying.Count == 0) {
rwls.ExitWriteLock();
are.WaitOne();
rwls.EnterWriteLock();
}
task = underlying.Dequeue();
} finally {
rwls.ExitWriteLock();
}
Process(task);
}
}对于我未受过训练的人来说,它似乎符合要求(当然,它有点难看),而且它与原始版本没有太大不同。
发布于 2010-04-22 23:54:09
基本上不是。它被优化以提供一些特定/常见的场景。如果你走出这些场景,它将不会工作。如果您需要Pulse等,请改用Monitor。
https://stackoverflow.com/questions/2691703
复制相似问题