A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-13.0/lock-object below:

Obey lock object semantics for lock statements - C# feature specifications

Note

This article is a feature specification. The specification serves as the design document for the feature. It includes proposed specification changes, along with information needed during the design and development of the feature. These articles are published until the proposed spec changes are finalized and incorporated in the current ECMA specification.

There may be some discrepancies between the feature specification and the completed implementation. Those differences are captured in the pertinent language design meeting (LDM) notes.

You can learn more about the process for adopting feature speclets into the C# language standard in the article on the specifications.

Champion issue: https://github.com/dotnet/csharplang/issues/7104

Summary

Special-case how System.Threading.Lock interacts with the lock keyword (calling its EnterScope method under the hood). Add static analysis warnings to prevent accidental misuse of the type where possible.

Motivation

.NET 9 is introducing a new System.Threading.Lock type as a better alternative to existing monitor-based locking. The presence of the lock keyword in C# might lead developers to think they can use it with this new type. Doing so wouldn't lock according to the semantics of this type but would instead treat it as any other object and would use monitor-based locking.

namespace System.Threading
{
    public sealed class Lock
    {
        public void Enter();
        public void Exit();
        public Scope EnterScope();
    
        public ref struct Scope
        {
            public void Dispose();
        }
    }
}
Detailed design

Semantics of the lock statement (§13.13) are changed to special-case the System.Threading.Lock type:

A lock statement of the form lock (x) { ... }

  1. where x is an expression of type System.Threading.Lock, is precisely equivalent to:
    using (x.EnterScope())
    {
        ...
    }
    
    and System.Threading.Lock must have the following shape:
    namespace System.Threading
    {
        public sealed class Lock
        {
            public Scope EnterScope();
    
            public ref struct Scope
            {
                public void Dispose();
            }
        }
    }
    
  2. where x is an expression of a reference_type, is precisely equivalent to: [...]

Note that the shape might not be fully checked (e.g., there will be no errors nor warnings if the Lock type is not sealed), but the feature might not work as expected (e.g., there will be no warnings when converting Lock to a derived type, since the feature assumes there are no derived types).

Additionally, new warnings are added to implicit reference conversions (§10.2.8) when upcasting the System.Threading.Lock type:

The implicit reference conversions are:

object l = new System.Threading.Lock(); // warning
lock (l) { } // monitor-based locking is used here

Note that this warning occurs even for equivalent explicit conversions.

The compiler avoids reporting the warning in some cases when the instance cannot be locked after converting to object:

var l = new System.Threading.Lock();
if (l != null) // no warning even though `l` is implicitly converted to `object` for `operator!=(object, object)`
    // ...

To escape out of the warning and force use of monitor-based locking, one can use

Alternatives Design meetings

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4