diff --git a/snippets/csharp/System.Threading/Lock/Overview/Project.csproj b/snippets/csharp/System.Threading/Lock/Overview/Project.csproj new file mode 100644 index 00000000000..0ea05c389bc --- /dev/null +++ b/snippets/csharp/System.Threading/Lock/Overview/Project.csproj @@ -0,0 +1,8 @@ + + + Exe + net9.0 + + true + + diff --git a/snippets/csharp/System.Threading/Lock/Overview/UsagePatterns.cs b/snippets/csharp/System.Threading/Lock/Overview/UsagePatterns.cs new file mode 100644 index 00000000000..14294e99d8e --- /dev/null +++ b/snippets/csharp/System.Threading/Lock/Overview/UsagePatterns.cs @@ -0,0 +1,47 @@ +using System; +using System.Threading; + +static class Program +{ + private static void Main() + { + var dataStructure = new ExampleDataStructure(); + dataStructure.Modify(); + } +} + +// +public sealed class ExampleDataStructure +{ + private readonly Lock _lockObj = new(); + + public void Modify() + { + lock (_lockObj) + { + // Critical section associated with _lockObj + } + + using (_lockObj.EnterScope()) + { + // Critical section associated with _lockObj + } + + _lockObj.Enter(); + try + { + // Critical section associated with _lockObj + } + finally { _lockObj.Exit(); } + + if (_lockObj.TryEnter()) + { + try + { + // Critical section associated with _lockObj + } + finally { _lockObj.Exit(); } + } + } +} +// diff --git a/xml/System.Threading/Lock.xml b/xml/System.Threading/Lock.xml index 0594396c4db..a0e5d0abe48 100644 --- a/xml/System.Threading/Lock.xml +++ b/xml/System.Threading/Lock.xml @@ -26,7 +26,9 @@ When using the or even in case of exceptions, such as in C# by using a `try/finally` block. - When the lock is being entered and exited in a C# `async` method, ensure that there is no `await` between the enter and exit. Locks are held by threads and the code following an `await` might run on a different thread. -It is recommended to use the method with a language construct that automatically disposes the returned such as the C# `using` keyword, or to use the C# `lock` keyword, as these ensure that the lock is exited in exceptional cases. These patterns might also have performance benefits over using `Enter/TryEnter` and `Exit`. +It is recommended to use the method with a language construct that automatically disposes the returned such as the C# `using` keyword, or to use the C# `lock` keyword, as these ensure that the lock is exited in exceptional cases. These patterns might also have performance benefits over using `Enter/TryEnter` and `Exit`. The following code fragment illustrates various patterns for entering and exiting a lock. + +:::code language="csharp" source="~/snippets/csharp/System.Threading/Lock/Overview/UsagePatterns.cs" id="Snippet1"::: When using the C# `lock` keyword or similar to enter and exit a lock, the type of the expression must be precisely `System.Threading.Lock`. If the type of the expression is anything else, such as `Object` or a generic type like `T`, a different implementation that is not interchangeable can be used instead (such as ). For more information, see the relevant [compiler speclet](https://github.com/dotnet/csharplang/blob/main/proposals/lock-object.md).