If a lock is known to be held or acquired, and then released within a method, then it must be released along all execution paths of that method.

Failing to do so will expose the conditional locking logic to the method’s callers and hence be deadlock-prone.

The types tracked by the rule are: Monitor, Mutex, ReaderWriterLock, ReaderWriterLockSlim and SpinLock from the System.Threading namespace.

Noncompliant Code Example

Class Example
    Private obj As Object = New Object()

    Public Sub DoSomethingWithMonitor()
        Monitor.Enter(obj) ' Noncompliant

        If IsInitialized() Then
            ' ..
            Monitor.Exit(obj)
        End If
    End Sub

    Private lockObj As ReaderWriterLockSlim = New ReaderWriterLockSlim()

    Public Sub DoSomethingWithReaderWriteLockSlim()
        lockObj.EnterReadLock() ' Noncompliant
        If IsInitialized() Then
            ' ..
            lockObj.ExitReadLock()
        End If
    End Sub
End Class

Compliant Solution

Class Example
    Private obj As Object = New Object()

    Public Sub DoSomethingWithMonitor()
        SyncLock obj ' is easier to use than explicit Monitor calls
            If IsInitialized() Then
            End If
        End SyncLock
    End Sub

    Private lockObj As ReaderWriterLockSlim = New ReaderWriterLockSlim()

    Public Sub DoSomethingWithReaderWriteLockSlim()
        lockObj.EnterReadLock()

        Try
            If IsInitialized() Then
            End If
        Finally
            lockObj.ExitReadLock()
        End Try
    End Sub
End Class

See