include::../why-dotnet.adoc[]

== How to fix it

To make sure that a lock is always released correctly, you can follow one of these two methods:

* Use a https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/synclock-statement[`SyncLock`] statement with your lock object.
* Use a https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/try-catch-finally-statement[`Try-Finally`] statement and put the release of your lock object within a https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/try-catch-finally-statement#finally-block[`Finally`] block.

=== Code examples

==== Noncompliant code example

[source,vbnet,diff-id=1,diff-type=noncompliant]
----
Class Example
    Private obj As Object = New Object()

    Public Sub DoSomethingWithMonitor()
        Monitor.Enter(obj) ' Noncompliant: not all paths release the lock

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

[source,vbnet,diff-id=2,diff-type=noncompliant]
----
Class Example
    Private lockObj As ReaderWriterLockSlim = New ReaderWriterLockSlim()

    Public Sub DoSomethingWithReaderWriteLockSlim()
        lockObj.EnterReadLock() ' Noncompliant: not all paths release the lock
        If IsInitialized() Then
            ' ...
            lockObj.ExitReadLock()
        End If
    End Sub
End Class
----

==== Compliant solution

[source,vbnet,diff-id=1,diff-type=noncompliant]
----
Class Example
    Private obj As Object = New Object()

    Public Sub DoSomethingWithMonitor()
        SyncLock obj ' Compliant: the lock will be released at the end of the SyncLock block
            If IsInitialized() Then 
                ' ...
            End If
        End SyncLock
    End Sub
End Class
----

[source,vbnet,diff-id=2,diff-type=noncompliant]
----
Class Example
    Private lockObj As ReaderWriterLockSlim = New ReaderWriterLockSlim()

    Public Sub DoSomethingWithReaderWriteLockSlim()
        lockObj.EnterReadLock() ' Compliant: the lock will be released in the finally block

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

include::../resources-dotnet.adoc[]

* https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/synclock-statement[`SyncLock` statement]
* https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/try-catch-finally-statement#finally-block[`Finally` block]

include::../rspecator.adoc[]
