A RetroSearch Logo

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

Search Query:

Showing content from https://github.com/dotnet/csharplang/issues/7104 below:

Lock statement pattern (VS 17.10, .NET 9) · Issue #7104 · dotnet/csharplang · GitHub

Lock statement pattern

(This proposal comes from @kouvel. I've populated this issue primarily with text he wrote in a separate document and augmented it with a few more details.)

Summary

Enable types to define custom behaviors for entering and exiting a lock when an instance of the type is used with the C# “lock” keyword.

Motivation

.NET 9 is likely to introduce a new dedicated System.Threading.Lock type. Along with other custom locks, the presence of the lock keyword in C# might lead developers to think they can use it in conjunction with this new type, but doing so won't actually lock according to the semantics of the lock type and would instead treat it as any arbitrary object for use with Monitor.

Detailed design Example

A type would expose the following to match the proposed pattern:

class Lock : ILockPattern
{
    public Scope EnterLockScope();

    public ref struct Scope
    {
        public void Dispose();
    }
}

public interface ILockPattern { }

EnterLockScope() would enter the lock and Dispose() would exit the lock. The behaviors of entering and exiting the lock are defined by the type.

The ILockPattern interface is a marker interface that indicates that usage of values of this type with the lock keyword would override the normal code generation for arbitrary objects. Instead, the compiler would lower the lock to use the lock pattern, e.g.:

class MyDataStructure
{
    private readonly Lock _lock = new();

    void Foo()
    {
        lock (_lock)
        {
            // do something
        }
    }
}

would be lowered to the equivalent of:

class MyDataStructure
{
    private readonly Lock _lock = new();

    void Foo()
    {
        using (_lock.EnterLockScope())
        {
            // do something
        }
    }
}
Lock pattern and behavior details

Consider a type L (Lock in this example) that may be used with the lock keyword. If L matches the lock pattern, it would meet all of the following criteria:

A marker interface ILockPattern is used to opt into the behaviors below, including through inheritance, and so that S may be defined by the user (for instance, as a ref struct). For a type L that implements interface ILockPattern:

SpinLock example

System.Threading.SpinLock (a struct) could expose such a holder:

struct SpinLock : ILockPattern
{
    [UnscopedRef]
    public Scope EnterLockScope();

    public ref struct Scope
    {
        public void Dispose();
    }
}

and then similarly be usable with lock whereas today as a struct it's not. When a variable of a struct type that matches the lock pattern is used with the lock keyword, it would be used by reference. Note the reference to SpinLock in the previous section.

Drawbacks Alternatives Unresolved questions Design meetings

https://github.com/dotnet/csharplang/blob/main/meetings/2023/LDM-2023-05-01.md#lock-statement-improvements
https://github.com/dotnet/csharplang/blob/main/meetings/2023/LDM-2023-10-16.md#lock-statement-pattern
https://github.com/dotnet/csharplang/blob/main/meetings/2023/LDM-2023-12-04.md#lock-statement-pattern

orthoxerox, timcassell, Unknown6656, jnm2, Rekkonnect and 18 moreIS4Code, miyu, fowl2, TonyValenti, vzarytovskii and 10 moreTahirAhmadov, miyu, koszeggy, OndrejPetrzilka and huoshan12345ViRuSTriNiTy


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