我有一个静态类,可以通过多个远程处理和应用程序线程的其他内部访问。该类功能的一部分是控制对各种文件的读写访问,因此我在文件列表上实现了静态ReaderWriterLock。该项目使用.net framework 2.0作为客户需求的一部分。

但是,当我使用多个不同的客户端(通常我使用的是16个)对系统进行压力测试时,每个客户端都执行大量读取和写入操作,然后就非常断断续续地进行,并且只有经过数小时甚至数天且至少有50万笔以上的交易完成后,系统崩溃。好的,所以我们有一个错误。

但是,当我查看所有锁定事件的日志时,可以看到发生了以下情况:

1:线程A直接获取写锁,检查IsWriterLock显示它为true。

2:线程B尝试获取读取器锁,即使线程A仍具有写锁,也会成功

3:系统现在崩溃,堆栈跟踪现在显示对readerwriterlock的空引用异常

此过程以前已经运行了数十万次,没有任何错误,我可以检查日志,并在以前的所有情况下都可以看到读锁被阻塞,直到退出写操作为止。我也曾尝试将readerwriterlock作为单例实现,但问题仍然存在

以前有没有人见过这样的东西?

下面显示了使用的readerwriterlock实现的精简版本:

private const int readwriterlocktimeoutms = 5000;
    private static ReaderWriterLock readerWriterLock = new ReaderWriterLock();


    // this method will be called by thread A
    public static void MethodA()
    {
        // bool to indicate that we have the lock
        bool IsTaken = false;

        try
        {
            // get the lock
            readerWriterLock.AcquireWriterLock(readwriterlocktimeoutms);

            // log that we have the lock for debug
            // Logger.LogInfo("MethodA: acquired write lock; writer lock held {0}; reader lock held {1}", readerWriterLock.IsWriterLockHeld.ToString(),readerWriterLock.IsReaderLockHeld.ToString(), );

            // mark that we have taken the lock
            IsTaken = true;
        }
        catch(Exception e)
        {
            throw new Exception(string.Format("Error getting lock {0} {1}", e.Message, Environment.StackTrace));
        }

        try
        {
           // do some work
        }
        finally
        {
            if (IsTaken)
            {
                readerWriterLock.ReleaseWriterLock();
            }
        }

    }

    // this method will be called by thread B
    public static void MethodB()
    {
        // bool to indicate that we have the lock
        bool IsTaken = false;

        try
        {
            // get the lock
            readerWriterLock.AcquireReaderLock(readwriterlocktimeoutms);

            // log that we have the lock for debug
            // Logger.LogInfo("MethodB: acquired read lock; writer lock held {0}; reader lock held {1}", readerWriterLock.IsWriterLockHeld.ToString(),readerWriterLock.IsReaderLockHeld.ToString(), );

            // mark that we have taken the lock
            IsTaken = true;
        }
        catch (Exception e)
        {
            throw new Exception(string.Format("Error getting lock {0} {1}", e.Message, Environment.StackTrace));
        }

        try
        {
           // do some work
        }
        finally
        {
            if (IsTaken)
            {
                readerWriterLock.ReleaseReaderLock();
            }
        }
    }

enter code here

最佳答案

@All终于解决了这个问题。 @Yannick,您的目标正确无误...

如果MSDN说不可能同时拥有读写器锁。

今天,我从Microsoft那里得到确认,如果多处理器系统上的负载非常重(请注意:我永远无法仅在Intel上在AMD系统上重现此问题),则ReaderWriterLock类对象可能会损坏,如果在任何给定阶段,作家的数量都会增加,因为他们可以在队列中进行备份。

在过去的两周中,我一直在使用.Net 3.5 ReaderWriterLockSlim类运行,并且没有遇到此问题,这与Microsoft确认的Readerwriterlockslim类与肥胖的ReaderWriterLock类没有相同的损坏风险相对应。

关于c# - readerwriterlock允许在获取写锁定的同时进行读取?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5777666/

10-10 23:13