c# - Silverlight ReaderWriterLock 实现好/坏?

标签 c# silverlight multithreading

我有一个 adopted为 Silverlight 实现一个简单的(无升级或超时)ReaderWriterLock,我想知道任何具有适当专业知识的人都可以验证它的设计是好是坏。对我来说它看起来很不错,它像宣传的那样工作,但我对多线程代码本身的经验有限。

public sealed class ReaderWriterLock
{
    private readonly object syncRoot = new object();    // Internal lock.
    private int i = 0;                                  // 0 or greater means readers can pass; -1 is active writer.
    private int readWaiters = 0;                        // Readers waiting for writer to exit.
    private int writeWaiters = 0;                       // Writers waiting for writer lock.
    private ConditionVariable conditionVar;             // Condition variable.

    public ReaderWriterLock()
    {
        conditionVar = new ConditionVariable(syncRoot);
    }

    /// <summary>
    /// Gets a value indicating if a reader lock is held.
    /// </summary>
    public bool IsReaderLockHeld
    {
        get
        {
            lock ( syncRoot )
            {
                if ( i > 0 )
                    return true;
                return false;
            }
        }
    }

    /// <summary>
    /// Gets a value indicating if the writer lock is held.
    /// </summary>
    public bool IsWriterLockHeld
    {
        get
        {
            lock ( syncRoot )
            {
                if ( i < 0 )
                    return true;
                return false;
            }
        }
    }

    /// <summary>
    /// Aquires the writer lock.
    /// </summary>
    public void AcquireWriterLock()
    {
        lock ( syncRoot )
        {
            writeWaiters++;
            while ( i != 0 )
                conditionVar.Wait();      // Wait until existing writer frees the lock.
            writeWaiters--;
            i = -1;             // Thread has writer lock.
        }
    }

    /// <summary>
    /// Aquires a reader lock.
    /// </summary>
    public void AcquireReaderLock()
    {
        lock ( syncRoot )
        {
            readWaiters++;
            // Defer to a writer (one time only) if one is waiting to prevent writer starvation.
            if ( writeWaiters > 0 )
            {
                conditionVar.Pulse();
                Monitor.Wait(syncRoot);
            }
            while ( i < 0 )
                Monitor.Wait(syncRoot);
            readWaiters--;
            i++;
        }
    }

    /// <summary>
    /// Releases the writer lock.
    /// </summary>
    public void ReleaseWriterLock()
    {
        bool doPulse = false;
        lock ( syncRoot )
        {
            i = 0;
            // Decide if we pulse a writer or readers.
            if ( readWaiters > 0 )
            {
                Monitor.PulseAll(syncRoot); // If multiple readers waiting, pulse them all.
            }
            else
            {
                doPulse = true;
            }
        }
        if ( doPulse )
            conditionVar.Pulse();                     // Pulse one writer if one waiting.
    }

    /// <summary>
    /// Releases a reader lock.
    /// </summary>
    public void ReleaseReaderLock()
    {
        bool doPulse = false;
        lock ( syncRoot )
        {
            i--;
            if ( i == 0 )
                doPulse = true;
        }
        if ( doPulse )
            conditionVar.Pulse();                     // Pulse one writer if one waiting.
    }

    /// <summary>
    /// Condition Variable (CV) class.
    /// </summary>
    public class ConditionVariable
    {
        private readonly object syncLock = new object(); // Internal lock.
        private readonly object m;                       // The lock associated with this CV.

        public ConditionVariable(object m)
        {
            lock (syncLock)
            {
                this.m = m;
            }
        }

        public void Wait()
        {
            bool enter = false;
            try
            {
                lock (syncLock)
                {
                    Monitor.Exit(m);
                    enter = true;
                    Monitor.Wait(syncLock);
                }
            }
            finally
            {
                if (enter)
                    Monitor.Enter(m);
            }
        }

        public void Pulse()
        {
            lock (syncLock)
            {
                Monitor.Pulse(syncLock);
            }
        }

        public void PulseAll()
        {
            lock (syncLock)
            {
                Monitor.PulseAll(syncLock);
            }
        }

    }

} 

如果它很好,它可能对其他人也有帮助,因为 Silverlight 目前缺少读写器类型的锁。谢谢。

最佳答案

我深入解释 Vance Morrison's ReaderWriterLock (在 .NET 3.5 中成为 ReaderWriterLockSlim)on my blog (低至 x86 级别)。这可能对您的设计有所帮助,尤其是了解事物的实际工作原理。

关于c# - Silverlight ReaderWriterLock 实现好/坏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/612765/

相关文章:

java - 这是没有 volatile 和同步开销的更好版本的 Double Check Locking

java - ThreadPool 执行器和大量客户端同时连接

c++信号处理程序可以唤醒线程吗?

c# - Windows 服务中的程序集未引用错误

c# - 无法使用 C# Rest Sharp 反序列化 Json

wpf - FrameworkElement.Loaded 事件如何与虚拟化配合使用?

c# - WPF中的轻量级处理动画资源?

c# - RelayCommand CanExecute 行为不起作用

c# - 如何在 C# 中读取表中选定单元格的数据并更新它

linux - Linux 上托管的 Silverlight