Note that there are some explanatory texts on larger screens.

plurals
  1. POreaderwriterlock allowing reads while write lock is acquired?
    primarykey
    data
    text
    <p>I have a static class which is accessed by multiple remoting and other internal to the application threads. Part of the functionality of this class is controlling read/write access to various files, so I've implemented a static ReaderWriterLock on the list of files. The project uses the .net framework 2.0 as part of the customer requirements.</p> <p>However when I stress test the system using a number of different clients (generally I'm using 16) each performing a large amount of reads and writes then very intermittently and only after several hours or even days have passed with at least 500k+ transactions completed the system crashes. Ok so we got a bug..</p> <p>But when I check the logs of all locking events I can see that the following has happened:</p> <p>1: Thread A acquires a write lock directly, checking IsWriterLock shows it to be true.</p> <p>2: Thread B tries to acquire a reader lock and <strong>succeeds</strong> even though Thread A still has the write lock</p> <p>3: System now crashes, stack trace now shows a null reference exception to the readerwriterlock</p> <p>This process has been run several hundred thousand times previously with no errors and I can check the logs and see that the read lock was blocked in all cases previously until the write had exited. I have also tried implementing the readerwriterlock as a singleton but the issue still occurs</p> <p>Has anybody ever seen anything like this before ??</p> <p>A slimed down version of the readerwriterlock implementation used is shown below:</p> <pre><code>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 </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload