Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/standard/threading/managed-threading-basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ ms.assetid: b2944911-0e8f-427d-a8bb-077550618935

The first five articles of this section are designed to help you determine when to use managed threading and to explain some basic features. For information on classes that provide additional features, see [Threading Objects and Features](threading-objects-and-features.md) and [Overview of Synchronization Primitives](overview-of-synchronization-primitives.md).

> [!NOTE]
> In .NET 9 and C# 13 or later, use a dedicated <xref:System.Threading.Lock?displayProperty=nameWithType> instance with the C# [lock statement](../../csharp/language-reference/statements/lock.md). This approach improves performance and reduces mistakes from locking the wrong object. In Visual Basic, continue to use [SyncLock](../../visual-basic/language-reference/statements/synclock-statement.md).
Comment on lines +16 to +17

Comment on lines +16 to +18
The remaining articles in this section cover advanced topics, including the interaction of managed threading with the Windows operating system.

> [!NOTE]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
title: "Managed Threading Best Practices"
description: Learn managed threading best practices in .NET. Work with difficult situations such as coordinating many threads or handling blocking threads.
ms.date: 03/13/2026
ai-usage: ai-assisted
dev_langs:
- "csharp"
- "vb"
Expand Down Expand Up @@ -95,6 +94,8 @@ Consider the following guidelines when using multiple threads:

- Use caution when locking on instances, for example `lock(this)` in C# or `SyncLock(Me)` in Visual Basic. If other code in your application, external to the type, takes a lock on the object, deadlocks could occur.

- In .NET 9 and C# 13 or later, use a dedicated <xref:System.Threading.Lock?displayProperty=nameWithType> instance as your lock object with the C# [lock statement](../../csharp/language-reference/statements/lock.md). In Visual Basic, continue to use a dedicated private reference type instance with `SyncLock`.

- Do ensure that a thread that has entered a monitor always leaves that monitor, even if an exception occurs while the thread is in the monitor. The C# [lock](../../csharp/language-reference/statements/lock.md) statement and the Visual Basic [SyncLock](../../visual-basic/language-reference/statements/synclock-statement.md) statement provide this behavior automatically, employing a **finally** block to ensure that <xref:System.Threading.Monitor.Exit*?displayProperty=nameWithType> is called. If you cannot ensure that **Exit** will be called, consider changing your design to use **Mutex**. A mutex is automatically released when the thread that currently owns it terminates.

- Do use multiple threads for tasks that require different resources, and avoid assigning multiple threads to a single resource. For example, any task involving I/O benefits from having its own thread, because that thread will block during I/O operations and thus allow other threads to execute. User input is another resource that benefits from a dedicated thread. On a single-processor computer, a task that involves intensive computation coexists with user input and with tasks that involve I/O, but multiple computation-intensive tasks contend with each other.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,13 @@ You can coordinate the interaction of threads that acquire a lock on the same ob
For more information, see the <xref:System.Threading.Monitor> API reference.

> [!NOTE]
> Use the [lock](../../csharp/language-reference/statements/lock.md) statement in C# and the [SyncLock](../../visual-basic/language-reference/statements/synclock-statement.md) statement in Visual Basic to synchronize access to a shared resource instead of using the <xref:System.Threading.Monitor> class directly. Those statements are implemented by using the <xref:System.Threading.Monitor.Enter*> and <xref:System.Threading.Monitor.Exit*> methods and a `try…finally` block to ensure that the acquired lock is always released.
> Use the [lock](../../csharp/language-reference/statements/lock.md) statement in C# and the [SyncLock](../../visual-basic/language-reference/statements/synclock-statement.md) statement in Visual Basic to synchronize access to a shared resource instead of using the <xref:System.Threading.Monitor> class directly.
>
> In .NET 9 and C# 13 or later, use a dedicated <xref:System.Threading.Lock?displayProperty=nameWithType> instance for best performance. In that case, `lock` uses <xref:System.Threading.Lock.EnterScope?displayProperty=nameWithType>.
>
Comment on lines 54 to +58
> This approach is better than locking a general `object` because it uses a lock type designed for synchronization and reduces accidental reuse of unrelated objects.
>
> Visual Basic doesn't support `System.Threading.Lock` in `SyncLock`, so use a dedicated private reference type for `SyncLock`. For C# versions before 13, for .NET versions before 9, and for Visual Basic, these statements use <xref:System.Threading.Monitor.Enter*> and <xref:System.Threading.Monitor.Exit*> with a `try…finally` block to ensure that the acquired lock is always released.

### Mutex class

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ When multiple threads can make calls to the properties and methods of a single o
Both Visual Basic and C# support the marking of blocks of code with a particular language keyword, the `lock` statement in C# or the `SyncLock` statement in Visual Basic. When the code is executed by a thread, an attempt is made to acquire the lock. If the lock has already been acquired by another thread, the thread blocks until the lock becomes available. When the thread exits the synchronized block of code, the lock is released, no matter how the thread exits the block.

> [!NOTE]
> Beginning in C# 13, the `lock` statement recognizes if the locked object is an instance of <xref:System.Threading.Lock?displayProperty=nameWithType> and uses the `EnterScope` method to create a synchronized region. The `lock`, when the target isn't a `Lock` instance, and `SyncLock` statements are implemented using <xref:System.Threading.Monitor.Enter*?displayProperty=nameWithType> and <xref:System.Threading.Monitor.Exit*?displayProperty=nameWithType>, so other methods of <xref:System.Threading.Monitor> can be used in conjunction with them within the synchronized region.
> In .NET 9 and C# 13 or later, if the `lock` target is a dedicated <xref:System.Threading.Lock?displayProperty=nameWithType> instance, the `lock` statement uses <xref:System.Threading.Lock.EnterScope?displayProperty=nameWithType> to create a synchronized region.
>
> Visual Basic doesn't support `System.Threading.Lock` in `SyncLock`, so continue to use `SyncLock` with a dedicated private reference type.
>
Comment on lines 48 to +52
> If the `lock` target isn't a `Lock` instance, and for all `SyncLock` usage, the compiler uses <xref:System.Threading.Monitor.Enter*?displayProperty=nameWithType> and <xref:System.Threading.Monitor.Exit*?displayProperty=nameWithType>. Because of that implementation, you can still use other <xref:System.Threading.Monitor> methods in the synchronized region.

You can also decorate a method with a <xref:System.Runtime.CompilerServices.MethodImplAttribute> with a value of <xref:System.Runtime.CompilerServices.MethodImplOptions.Synchronized?displayProperty=nameWithType>, which has the same effect as using <xref:System.Threading.Monitor> or one of the compiler keywords to lock the entire body of the method.

Expand Down
3 changes: 3 additions & 0 deletions docs/standard/threading/threading-objects-and-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ Along with the <xref:System.Threading.Thread?displayProperty=nameWithType> class
|[SpinLock](spinlock.md)|Describes the <xref:System.Threading.SpinLock?displayProperty=nameWithType> structure, which is a lightweight alternative to the <xref:System.Threading.Monitor?displayProperty=nameWithType> class for certain low-level locking scenarios.|
|[SpinWait](spinwait.md)|Describes the <xref:System.Threading.SpinWait?displayProperty=nameWithType> structure, which provides support for spin-based waiting.|

> [!NOTE]
> In .NET 9 and C# 13 or later, prefer a dedicated <xref:System.Threading.Lock?displayProperty=nameWithType> instance with the C# `lock` statement for general locking scenarios. This approach improves performance and reduces mistakes from locking shared objects that weren't meant for synchronization. For details, see [Overview of synchronization primitives](overview-of-synchronization-primitives.md) and [The lock statement](../../csharp/language-reference/statements/lock.md). In Visual Basic, continue to use `SyncLock`.
Comment on lines +27 to +28
Comment on lines 24 to +28

## See also

- <xref:System.Threading.Monitor?displayProperty=nameWithType>
Expand Down
Loading