Why is this an issue?
If a lock is held or acquired and then released within a method, it should be released along all execution paths.
Failing to do so could make an application deadlock-prone because there is a risk of the lock not being released.
The types tracked by the rule are: Monitor
, Mutex
, ReaderWriterLock
, ReaderWriterLockSlim
, and
SpinLock
from the System.Threading
namespace.
This rule raises an issue when a lock is acquired in a method but only released on some paths. No issue is raised when the lock is never released
in the method. The assumption is that callers will release it.
Noncompliant code example
class MyClass
{
private object obj = new object();
public void DoSomethingWithMonitor()
{
Monitor.Enter(obj); // Noncompliant
if (IsInitialized())
{
// ...
Monitor.Exit(obj);
}
}
private ReaderWriterLockSlim lockObj = new ReaderWriterLockSlim();
public void DoSomethingWithReaderWriteLockSlim()
{
lockObj.EnterReadLock(); // Noncompliant
if (IsInitialized())
{
// ...
lockObj.ExitReadLock();
}
}
}
Compliant solution
class MyClass
{
private object obj = new object();
public void DoSomethingWithMonitor()
{
lock(obj) // lock() {...} is easier to use than explicit Monitor calls
{
if (IsInitialized())
{
}
}
}
private ReaderWriterLockSlim lockObj = new ReaderWriterLockSlim();
public void DoSomethingWithReaderWriteLockSlim()
{
lockObj.EnterReadLock();
try
{
if (IsInitialized())
{
}
}
finally
{
lockObj.ExitReadLock();
}
}
}
Resources