This rule raises an issue when a field used in a lock statement is declared with type object or another non-specialized
type instead of System.Threading.Lock.
This applies to projects targeting C# 13 and .NET 9 or later, where System.Threading.Lock is available.
Why is this an issue?
When using the lock statement in C#, you need an object to serve as the synchronization point. Traditionally, developers have used
private readonly object _lock = new(); for this purpose.
Starting with C# 13 and .NET 9, Microsoft introduced System.Threading.Lock as a dedicated type specifically designed for use with
lock statements. This new type offers several advantages:
- Better performance:
System.Threading.Lockis optimized for locking scenarios and can provide performance improvements over the traditionalobject-based approach - Clearer intent: Using a dedicated lock type makes your code’s synchronization intent explicit
- Type safety: The compiler can better understand and optimize code using the specialized type
Continuing to use object or other non-specialized types for lock fields means missing out on these benefits, especially in
performance-critical code sections.
What is the potential impact?
Using object instead of System.Threading.Lock for synchronization can lead to:
- Performance degradation: The traditional
Monitor-based synchronization used withobjectis less efficient than the optimized implementation ofSystem.Threading.Lock - Less maintainable code: Using a generic
objecttype doesn’t clearly communicate that the field is intended exclusively for synchronization - Missed optimization opportunities: The compiler and runtime can apply specific optimizations when they recognize the dedicated lock type
How to fix it
Change the field declaration from object to System.Threading.Lock. All existing lock statements using the
field continue to work without modification.
Note: This fix requires your project to target .NET 9 or later and use C# 13 or later.
Code examples
Noncompliant code example
public class Sample
{
readonly List<int> _list = [];
readonly object _lock = new(); // Noncompliant
public void Add(int k)
{
lock (_lock)
{
_list.Add(k);
}
}
}
Compliant solution
public class Sample
{
readonly List<int> _list = [];
readonly Lock _lock = new();
public void Add(int k)
{
lock (_lock)
{
_list.Add(k);
}
}
}
Resources
Documentation
- Microsoft Learn - Lock Class
- Microsoft Learn - lock statement - C# reference
- Microsoft DevBlogs - Performance Improvements in .NET 9 - Lock object