S9422 — Lock object fields should use "System.Threading.Lock" type

Language
C#
Type
Code smell
Severity
Major
Tags
threading, performance, modernization

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:

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:

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

↑ Back to top