I’d like to propose the following rule:
Prefer usage of System.Threading.Lock over object for lock statements
With the introduction of System.Threading.Lock in .NET 9.0, it is preferred to use this type for dedicated lock objects, over the use of object. This improves the safety, performance, and clarity of thread coordination in multi-threaded applications.
Non-compliant
class NonCompliant
{
private static readonly object Locker = new();
void UseLock()
{
lock (Locker) // Non-compliant {{Prefer a lock object of the type System.Threading.Lock.}}
{
// ...
}
}
}
Compliant
class Compliant
{
private static readonly System.Threading.Lock Locker = new();
void UseLock()
{
lock (Locker)
{
// ...
}
lock (this) // Compliant, as this is not of the type System.Object.
{
// ...
}
}
}
Tip, when dealing with multi-target solutions, it might be worth to use the following using statements:
#if NET9_0_OR_GREATER
global using Lock = System.Threading.Lock;
#else
global using Lock = object;
#endif
See also: