首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ReaderWriterLockSlim和脉冲/等待

ReaderWriterLockSlim和脉冲/等待
EN

Stack Overflow用户
提问于 2010-04-22 22:31:02
回答 2查看 657关注 0票数 2

有没有Monitor.PulseMonitor.Wait的等价物可以与ReaderWriterLockSlim一起使用

我有一个类,其中封装了对底层队列的多线程访问。要将某物入队,我需要获取一个保护底层队列(以及其他几个对象)的锁,然后添加该项并锁定( Monitor.Pulse )对象,以发出某物被添加到队列的信号。

代码语言:javascript
复制
public void Enqueue(ITask task)
{
    lock (mutex)
    {
        underlying.Enqueue(task);
        Monitor.Pulse(mutex);
    }
}

在队列的另一端,我有一个后台线程,它在消息到达队列时持续处理消息。当队列中没有项目时,它使用Monitor.Wait,以避免不必要的轮询。(我认为这是一个好的设计,但是任何火焰(在合理的范围内)都是受欢迎的,如果它们能帮助我学习的话。)

代码语言:javascript
复制
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设计。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-04-23 06:39:16

在尝试了一下(在接受了Mark的挑战之后(我同意,我的改变并不完全是基本的)),我想出了这个组合:

代码语言:javascript
复制
ReaderWriterLockSlim rwls;
AutoResetEvent are;
代码语言:javascript
复制
public void Enqueue(ITask task) {
    rwls.EnterWriteLock();
    try {
        underlying.Enqueue(task);
        if (underlying.Count == 1) {
          are.Set();
        }
    } finally {
        rwls.ExitWriteLock();
    }
}
代码语言:javascript
复制
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);
    }
}

对于我未受过训练的人来说,它似乎符合要求(当然,它有点难看),而且它与原始版本没有太大不同。

票数 0
EN

Stack Overflow用户

发布于 2010-04-22 23:54:09

基本上不是。它被优化以提供一些特定/常见的场景。如果你走出这些场景,它将不会工作。如果您需要Pulse等,请改用Monitor

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2691703

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档