From f68257dac0bd1618bd33d94978927572852d503c Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Tue, 11 Aug 2026 06:45:39 -0400 Subject: [PATCH 1/3] add support for Lock objects Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/conversions.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/standard/conversions.md b/standard/conversions.md index f0a446eef..b94ad3f88 100644 --- a/standard/conversions.md +++ b/standard/conversions.md @@ -166,9 +166,9 @@ An implicit conversion exists from the `null` literal to any reference type or n The implicit reference conversions are: - A null literal conversion ([§10.2.7](conversions.md#1027-null-literal-conversions)) to any *reference_type*. -- From any *reference_type* to `object` and `dynamic`. -- From any *class_type* `S` to any *class_type* `T`, provided `S` is derived from `T`. -- From any *class_type* `S` to any *interface_type* `T`, provided `S` implements `T`. +- From any *reference_type* to `object` and `dynamic`. A warning shall be issued when *reference_type* is `System.Threading.Lock`. +- From any *class_type* `S` to any *class_type* `T`, provided `S` is derived from `T`. A warning shall be issued when `S` is `System.Threading.Lock`. +- From any *class_type* `S` to any *interface_type* `T`, provided `S` implements `T`. A warning shall be issued when `S` is `System.Threading.Lock`. - From any *interface_type* `S` to any *interface_type* `T`, provided `S` is derived from `T`. - From an *array_type* `S` with an element type `Sᵢ` to an *array_type* `T` with an element type `Tᵢ`, provided all of the following are true: - `S` and `T` differ only in element type. In other words, `S` and `T` have the same number of dimensions. From d8e9852b73a2a40270fa018cdddeb81be8087759 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Tue, 11 Aug 2026 06:50:16 -0400 Subject: [PATCH 2/3] add support for Lock objects Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/statements.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/standard/statements.md b/standard/statements.md index 33e67e45b..039641e88 100644 --- a/standard/statements.md +++ b/standard/statements.md @@ -2027,7 +2027,7 @@ A `lock` statement of the form `lock (x)` … -where `x` is an expression of a *reference_type*, is precisely equivalent to: +where `x` is an expression of a *reference_type* other than `System.Threading.Lock`, is precisely equivalent to: ```csharp bool __lockWasTaken = false; @@ -2047,8 +2047,25 @@ finally except that `x` is only evaluated once. +A `lock` statement of the form + +`lock (x)` … + +where `x` is an expression of type `System.Threading.Lock`, is precisely equivalent to: + +```csharp +using (x.EnterScope()) +{ + … +} +``` + +Note carefully that when `x` is an expression of type `System.Threading.Lock`, the statements `lock (x) …` and `lock ((object)x) …` are treated quite differently. The former uses the `Lock`/`Scope` approach described above while the latter uses the `Monitor.Enter`/`Exit` approach described earlier, as the expression does not have type `System.Threading.Lock` in the latter case, and a warning to that effect is reported. + While a mutual-exclusion lock is held, code executing in the same execution thread can also obtain and release the lock. However, code executing in other threads is blocked from obtaining the lock until the lock is released. +It is a compile-time error to use a lock statement on a value of type 'System.Threading.Lock' in an async method or async lambda expression. + ## 13.14 The using statement ### 13.14.1 General From 96be765115ea4579b76a3651cd96e98273d9b21c Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Tue, 11 Aug 2026 06:56:23 -0400 Subject: [PATCH 3/3] add support for Lock objects Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/standard-library.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/standard/standard-library.md b/standard/standard-library.md index 6f1ee5790..2743b9a05 100644 --- a/standard/standard-library.md +++ b/standard/standard-library.md @@ -1031,6 +1031,16 @@ namespace System.Threading { public bool IsCancellationRequested { get; } } + + public sealed class Lock + { + public Lock(); + public System.Threading.Lock.Scope EnterScope(); + public ref struct Lock.Scope + { + public void Dispose(); + } + } } namespace System.Threading.Tasks @@ -1557,6 +1567,8 @@ The following library types are referenced in this specification. The full names - `global::System.Runtime.CompilerServices.ValueTaskAwaiter` - `global::System.Runtime.CompilerServices.Unsafe` - `global::System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute` +- `global::System.Threading.Lock` +- `global::System.Threading.Lock.Scope` - `global::System.Threading.Monitor` - `global::System.Threading.Tasks.Task` - `global::System.Threading.Tasks.Task`