2

I have a frustration with ReaderWriterLockSlim and delaying ExitWriteLock. Why is the WriteLock released in timers callback?

var _lock = new ReaderWriterLockSlim();
_lock.EnterWriteLock();
Assert.AreEqual(true, _lock.IsWriteLockHeld);   // good

System.Threading.Timer timer = new Timer(state =>
{
    _lock.ExitWriteLock(); //throws exception that lock is not held
}, null, 1, -1);

Thread.Sleep(1000);
Assert.AreEqual(false, _lock.IsWriteLockHeld);
Andrey Ershov
  • 1,773
  • 1
  • 16
  • 26
  • 2
    Can you explain what exactly you expect this code to do? What type is this `Timer`? Also, see MSDN: [`IsWriteLockHeld` returns _"a value that indicates whether **the current thread** has entered the lock in write mode"_](https://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.iswritelockheld(v=vs.110).aspx)... – CodeCaster Jan 29 '15 at 09:34

1 Answers1

5

By the looks of the constructor, you're using a System.Threading.Timer. The callback of that timer runs on a threadpool thread.

The write lock isn't released, it's just that the callback you specified for the Timer runs on a different thread, and that thread doesn't hold the write lock, so the assertion Assert.AreEqual(true, _lock.IsWriteLockHeld); in the callback fails, causing an exception.

One thread enters a lock, and only for that thread does IsWriteLockHeld hold true, and only that thread can exit the lock.

Willem van Rumpt
  • 6,490
  • 2
  • 32
  • 44
  • I've edited the question, ExitWriteLock also throws exception. But let me guess, only a thread, that holds a lock can exit it ? – Andrey Ershov Jan 29 '15 at 09:50
  • @aershov you can use a SemaphoreSlim here if you don't need reader-writer semantics. – usr Jan 29 '15 at 09:59