rspec/rules/S2222/csharp/rule.adoc

101 lines
2.3 KiB
Plaintext
Raw Normal View History

2023-06-06 16:02:42 +02:00
include::../why-dotnet.adoc[]
2023-06-06 16:02:42 +02:00
== How to fix it
2023-06-06 16:02:42 +02:00
To make sure that a lock is always released correctly, you can follow one of these two methods:
2023-06-06 16:02:42 +02:00
* Use a https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/lock[`lock`] statement with your lock object.
* Use a https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/exception-handling-statements#the-try-finally-statement[`try-finally`] statement and put the release of your lock object within the finally block.
=== Code examples
==== Noncompliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
----
class MyClass
{
private object obj = new object();
public void DoSomethingWithMonitor()
{
2023-06-06 16:02:42 +02:00
Monitor.Enter(obj); // Noncompliant: not all paths release the lock
if (IsInitialized())
{
// ...
Monitor.Exit(obj);
}
}
2023-06-06 16:02:42 +02:00
}
----
2023-06-06 16:02:42 +02:00
[source,csharp,diff-id=2,diff-type=noncompliant]
----
class MyClass
{
private ReaderWriterLockSlim lockObj = new ReaderWriterLockSlim();
public void DoSomethingWithReaderWriteLockSlim()
{
2023-06-06 16:02:42 +02:00
lockObj.EnterReadLock(); // Noncompliant: not all paths release the lock
if (IsInitialized())
{
// ...
lockObj.ExitReadLock();
}
}
}
----
2023-06-06 16:02:42 +02:00
==== Compliant solution
2023-06-06 16:02:42 +02:00
[source,csharp,diff-id=1,diff-type=noncompliant]
----
class MyClass
{
private object obj = new object();
public void DoSomethingWithMonitor()
{
2023-06-07 15:41:34 +02:00
lock(obj) // Compliant: the lock will be released at the end of the lock block
{
if (IsInitialized())
{
2023-06-06 16:02:42 +02:00
// ...
}
}
}
2023-06-06 16:02:42 +02:00
}
----
2023-06-06 16:02:42 +02:00
[source,csharp,diff-id=2,diff-type=noncompliant]
----
class MyClass
{
private ReaderWriterLockSlim lockObj = new ReaderWriterLockSlim();
public void DoSomethingWithReaderWriteLockSlim()
{
2023-06-07 15:41:34 +02:00
lockObj.EnterReadLock(); // Compliant: the lock will be released in the finally block
try
{
if (IsInitialized())
{
2023-06-06 16:02:42 +02:00
// ...
}
}
finally
{
lockObj.ExitReadLock();
}
}
}
----
2023-06-06 16:02:42 +02:00
include::../resources-dotnet.adoc[]
2023-06-06 16:02:42 +02:00
* https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/lock[`lock` statement]
* https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/exception-handling-statements#the-try-finally-statement[The `try-finally` statement]
2023-06-06 16:02:42 +02:00
include::../rspecator.adoc[]