diff --git a/.openpublishing.redirection.csharp.json b/.openpublishing.redirection.csharp.json index a061d57088c43..b5fde9344ae1e 100644 --- a/.openpublishing.redirection.csharp.json +++ b/.openpublishing.redirection.csharp.json @@ -563,6 +563,10 @@ "source_path_from_root": "/docs/csharp/language-reference/keywords/literal-keywords.md", "redirect_url": "/dotnet/csharp/language-reference/keywords/null" }, + { + "source_path_from_root": "/docs/csharp/language-reference/keywords/lock-statement.md", + "redirect_url": "/dotnet/csharp/language-reference/statements/lock" + }, { "source_path_from_root": "/docs/csharp/language-reference/keywords/long.md", "redirect_url": "/dotnet/csharp/language-reference/builtin-types/integral-numeric-types" diff --git a/docs/csharp/language-reference/keywords/index.md b/docs/csharp/language-reference/keywords/index.md index e6b1d2ad3a825..5eeeaa9991b37 100644 --- a/docs/csharp/language-reference/keywords/index.md +++ b/docs/csharp/language-reference/keywords/index.md @@ -58,7 +58,7 @@ The first table in this topic lists keywords that are reserved identifiers in an [interface](interface.md) [internal](internal.md) [is](../operators/is.md) - [lock](lock-statement.md) + [lock](../statements/lock.md) [long](../builtin-types/integral-numeric-types.md) :::column-end::: :::column::: diff --git a/docs/csharp/language-reference/keywords/statement-keywords.md b/docs/csharp/language-reference/keywords/statement-keywords.md index ba45d41590ac8..27aa0c3da537d 100644 --- a/docs/csharp/language-reference/keywords/statement-keywords.md +++ b/docs/csharp/language-reference/keywords/statement-keywords.md @@ -19,7 +19,7 @@ Statements are program instructions. Except as described in the topics reference |Exception handling statements|[throw](throw.md), [try-catch](try-catch.md), [try-finally](try-finally.md), [try-catch-finally](try-catch-finally.md)| |[Checked and unchecked](checked-and-unchecked.md)|[checked](checked.md), [unchecked](unchecked.md)| |[fixed statement](fixed-statement.md)|[fixed](fixed-statement.md)| -|[lock statement](lock-statement.md)|[lock](lock-statement.md)| +|[lock statement](../statements/lock.md)|`lock`| |[yield statement](yield.md)|`yield`| ## See also diff --git a/docs/csharp/language-reference/keywords/volatile.md b/docs/csharp/language-reference/keywords/volatile.md index ee308e11decf7..2daa824fe6828 100644 --- a/docs/csharp/language-reference/keywords/volatile.md +++ b/docs/csharp/language-reference/keywords/volatile.md @@ -25,7 +25,7 @@ The `volatile` keyword can be applied to fields of these types: - Generic type parameters known to be reference types. - and . -Other types, including `double` and `long`, cannot be marked `volatile` because reads and writes to fields of those types cannot be guaranteed to be atomic. To protect multi-threaded access to those types of fields, use the class members or protect access using the [`lock`](lock-statement.md) statement. +Other types, including `double` and `long`, cannot be marked `volatile` because reads and writes to fields of those types cannot be guaranteed to be atomic. To protect multi-threaded access to those types of fields, use the class members or protect access using the [`lock`](../statements/lock.md) statement. The `volatile` keyword can only be applied to fields of a `class` or `struct`. Local variables cannot be declared `volatile`. @@ -52,5 +52,5 @@ With the `volatile` modifier added to the declaration of `_shouldStop` in place, - [C# Programming Guide](../../programming-guide/index.md) - [C# Keywords](index.md) - [Modifiers](index.md) -- [lock statement](lock-statement.md) +- [lock statement](../statements/lock.md) - diff --git a/docs/csharp/language-reference/operators/await.md b/docs/csharp/language-reference/operators/await.md index f42757809a2df..fe33159d8f112 100644 --- a/docs/csharp/language-reference/operators/await.md +++ b/docs/csharp/language-reference/operators/await.md @@ -22,7 +22,7 @@ The preceding example uses the [async `Main` method](../../fundamentals/program- > [!NOTE] > For an introduction to asynchronous programming, see [Asynchronous programming with async and await](../../programming-guide/concepts/async/index.md). Asynchronous programming with `async` and `await` follows the [task-based asynchronous pattern](../../../standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap.md). -You can use the `await` operator only in a method, [lambda expression](lambda-expressions.md), or [anonymous method](delegate-operator.md) that is modified by the [async](../keywords/async.md) keyword. Within an async method, you can't use the `await` operator in the body of a synchronous function, inside the block of a [lock statement](../keywords/lock-statement.md), and in an [unsafe](../keywords/unsafe.md) context. +You can use the `await` operator only in a method, [lambda expression](lambda-expressions.md), or [anonymous method](delegate-operator.md) that is modified by the [async](../keywords/async.md) keyword. Within an async method, you can't use the `await` operator in the body of a synchronous function, inside the block of a [lock statement](../statements/lock.md), and in an [unsafe](../keywords/unsafe.md) context. The operand of the `await` operator is usually of one of the following .NET types: , , , or . However, any awaitable expression can be the operand of the `await` operator. For more information, see the [Awaitable expressions](~/_csharplang/spec/expressions.md#awaitable-expressions) section of the [C# language specification](~/_csharplang/spec/introduction.md). diff --git a/docs/csharp/language-reference/keywords/lock-statement.md b/docs/csharp/language-reference/statements/lock.md similarity index 89% rename from docs/csharp/language-reference/keywords/lock-statement.md rename to docs/csharp/language-reference/statements/lock.md index 6c780123c225e..752c78be47e9e 100644 --- a/docs/csharp/language-reference/keywords/lock-statement.md +++ b/docs/csharp/language-reference/statements/lock.md @@ -22,7 +22,7 @@ lock (x) } ``` -where `x` is an expression of a [reference type](reference-types.md). It's precisely equivalent to +where `x` is an expression of a [reference type](../keywords/reference-types.md). It's precisely equivalent to ```csharp object __lockObj = x; @@ -38,7 +38,7 @@ finally } ``` -Since the code uses a [try...finally](try-finally.md) block, the lock is released even if an exception is thrown within the body of a `lock` statement. +Since the code uses a [try...finally](../keywords/try-finally.md) block, the lock is released even if an exception is thrown within the body of a `lock` statement. You can't use the [await operator](../operators/await.md) in the body of a `lock` statement. @@ -56,7 +56,7 @@ Hold a lock for as short time as possible to reduce lock contention. The following example defines an `Account` class that synchronizes access to its private `balance` field by locking on a dedicated `balanceLock` instance. Using the same instance for locking ensures that the `balance` field cannot be updated simultaneously by two threads attempting to call the `Debit` or `Credit` methods simultaneously. -[!code-csharp[lock-statement-example](snippets/LockStatementExample.cs)] +:::code language="csharp" source="snippets/lock/Program.cs"::: ## C# language specification @@ -65,7 +65,6 @@ For more information, see [The lock statement](~/_csharplang/spec/statements.md# ## See also - [C# reference](../index.md) -- [C# keywords](index.md) - - - diff --git a/docs/csharp/language-reference/keywords/snippets/LockStatementExample.cs b/docs/csharp/language-reference/statements/snippets/lock/Program.cs similarity index 100% rename from docs/csharp/language-reference/keywords/snippets/LockStatementExample.cs rename to docs/csharp/language-reference/statements/snippets/lock/Program.cs diff --git a/docs/csharp/language-reference/statements/snippets/lock/lock.csproj b/docs/csharp/language-reference/statements/snippets/lock/lock.csproj new file mode 100644 index 0000000000000..74abf5c976649 --- /dev/null +++ b/docs/csharp/language-reference/statements/snippets/lock/lock.csproj @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + + diff --git a/docs/csharp/misc/cs0185.md b/docs/csharp/misc/cs0185.md index 7ae062f2edc91..7538a6a7e7589 100644 --- a/docs/csharp/misc/cs0185.md +++ b/docs/csharp/misc/cs0185.md @@ -12,7 +12,7 @@ ms.assetid: d6546e10-0af3-4860-8e6f-2da7dbeb3d28 'type' is not a reference type as required by the lock statement - The [lock](../language-reference/keywords/lock-statement.md) statement can only be used with [reference types](../language-reference/keywords/reference-types.md). + The [lock](../language-reference/statements/lock.md) statement can only be used with [reference types](../language-reference/keywords/reference-types.md). ## Example diff --git a/docs/csharp/programming-guide/statements-expressions-operators/statements.md b/docs/csharp/programming-guide/statements-expressions-operators/statements.md index 74cb0e3842c8e..531a1e4552b67 100644 --- a/docs/csharp/programming-guide/statements-expressions-operators/statements.md +++ b/docs/csharp/programming-guide/statements-expressions-operators/statements.md @@ -31,7 +31,7 @@ The following table lists the various types of statements in C# and their associ |The `await` statement|If you mark a method with the [async](../../language-reference/keywords/async.md) modifier, you can use the [await](../../language-reference/operators/await.md) operator in the method. When control reaches an `await` expression in the async method, control returns to the caller, and progress in the method is suspended until the awaited task completes. When the task is complete, execution can resume in the method.

For a simple example, see the "Async Methods" section of [Methods](../classes-and-structs/methods.md). For more information, see [Asynchronous Programming with async and await](../concepts/async/index.md).| |The `yield return` statement|An iterator performs a custom iteration over a collection, such as a list or an array. An iterator uses the [yield return](../../language-reference/keywords/yield.md) statement to return each element one at a time. When a `yield return` statement is reached, the current location in code is remembered. Execution is restarted from that location when the iterator is called the next time.

For more information, see [Iterators](../concepts/iterators.md).| |The `fixed` statement|The fixed statement prevents the garbage collector from relocating a movable variable. For more information, see [fixed](../../language-reference/keywords/fixed-statement.md).| -|The `lock` statement|The lock statement enables you to limit access to blocks of code to only one thread at a time. For more information, see [lock](../../language-reference/keywords/lock-statement.md).| +|The `lock` statement|The lock statement enables you to limit access to blocks of code to only one thread at a time. For more information, see [lock](../../language-reference/statements/lock.md).| |Labeled statements|You can give a statement a label and then use the [goto](../../language-reference/statements/jump-statements.md#the-goto-statement) keyword to jump to the labeled statement. (See the example in the following row.)| |The [empty statement](#the-empty-statement)|The empty statement consists of a single semicolon. It does nothing and can be used in places where a statement is required but no action needs to be performed.| diff --git a/docs/csharp/toc.yml b/docs/csharp/toc.yml index 6541f6c4b44e6..998c44e0d8a53 100644 --- a/docs/csharp/toc.yml +++ b/docs/csharp/toc.yml @@ -1002,8 +1002,6 @@ items: href: language-reference/keywords/unchecked.md - name: fixed Statement href: language-reference/keywords/fixed-statement.md - - name: lock Statement - href: language-reference/keywords/lock-statement.md - name: Method Parameters items: - name: Passing parameters @@ -1214,6 +1212,9 @@ items: - name: Jump statements displayName: break, continue, goto, return href: language-reference/statements/jump-statements.md + - name: lock statement + displayName: thread synchronization, monitor + href: language-reference/statements/lock.md - name: Special characters items: - name: Overview diff --git a/docs/framework/debug-trace-profile/dangerousthreadingapi-mda.md b/docs/framework/debug-trace-profile/dangerousthreadingapi-mda.md index 807f28adf6afe..4c05041300615 100644 --- a/docs/framework/debug-trace-profile/dangerousthreadingapi-mda.md +++ b/docs/framework/debug-trace-profile/dangerousthreadingapi-mda.md @@ -71,4 +71,4 @@ Thread t = new Thread(delegate() { Thread.Sleep(1000); }); - - [Diagnosing Errors with Managed Debugging Assistants](diagnosing-errors-with-managed-debugging-assistants.md) -- [lock Statement](../../csharp/language-reference/keywords/lock-statement.md) +- [lock Statement](../../csharp/language-reference/statements/lock.md) diff --git a/docs/framework/performance/reliability-best-practices.md b/docs/framework/performance/reliability-best-practices.md index ce62fd095bc94..7ca857b53de13 100644 --- a/docs/framework/performance/reliability-best-practices.md +++ b/docs/framework/performance/reliability-best-practices.md @@ -111,7 +111,7 @@ Use for cleaning up operating s The CLR must know when code is in a lock so that it will know to tear down the rather than just aborting the thread. Aborting the thread could be dangerous as the data operated on by the thread could be left in an inconsistent state. Therefore, the entire has to be recycled. The consequences of failing to identify a lock can be either deadlocks or incorrect results. Use the methods and to identify lock regions. They are static methods on the class that only apply to the current thread, helping to prevent one thread from editing another thread’s lock count. - and have this CLR notification built in, so their usage is recommended as well as the use of the [lock Statement](../../csharp/language-reference/keywords/lock-statement.md), which uses these methods. + and have this CLR notification built in, so their usage is recommended as well as the use of the [lock Statement](../../csharp/language-reference/statements/lock.md), which uses these methods. Other locking mechanisms such as spin locks and must call these methods to notify the CLR that a critical section is being entered. These methods do not take any locks; they inform the CLR that code is executing in a critical section and aborting the thread could leave shared state inconsistent. If you have defined your own lock type, such as a custom class, use these lock count methods. @@ -137,7 +137,7 @@ If code uses a COM object, avoid sharing that COM object between application dom ### Locks do not work process-wide or between application domains. -In the past, and the [lock Statement](../../csharp/language-reference/keywords/lock-statement.md) have been used to create global process locks. For example, this occurs when locking on agile classes, such as instances from non-shared assemblies, objects, interned strings, and some strings shared across application domains using remoting. These locks are no longer process-wide. To identify the presence of a process-wide interapplication domain lock, determine if the code within the lock uses any external, persisted resource such as a file on disk or possibly a database. +In the past, and the [lock Statement](../../csharp/language-reference/statements/lock.md) have been used to create global process locks. For example, this occurs when locking on agile classes, such as instances from non-shared assemblies, objects, interned strings, and some strings shared across application domains using remoting. These locks are no longer process-wide. To identify the presence of a process-wide interapplication domain lock, determine if the code within the lock uses any external, persisted resource such as a file on disk or possibly a database. Note that taking a lock within an might cause problems if the protected code uses an external resource because that code may run simultaneously across multiple application domains. This can be a problem when writing to one log file or binding to a socket for the entire process. These changes mean there is no easy way, using managed code, to get a process-global lock, other than using a named or instance. Create code that does not run in two application domains simultaneously, or use the or classes. If existing code cannot be changed, do not use a Win32 named mutex to achieve this synchronization because running in fiber mode means you cannot guarantee the same operating system thread will acquire and release a mutex. You must use the managed class, or a named , , or a to synchronize the code lock in a manner that the CLR is aware of instead of synchronizing the lock using unmanaged code. diff --git a/docs/fundamentals/code-analysis/quality-rules/ca2002.md b/docs/fundamentals/code-analysis/quality-rules/ca2002.md index 875847416faea..af6279946a2e4 100644 --- a/docs/fundamentals/code-analysis/quality-rules/ca2002.md +++ b/docs/fundamentals/code-analysis/quality-rules/ca2002.md @@ -79,5 +79,5 @@ The following example shows some object locks that violate the rule. - - -- [lock Statement (C#)](../../../csharp/language-reference/keywords/lock-statement.md) +- [lock Statement (C#)](../../../csharp/language-reference/statements/lock.md) - [SyncLock Statement (Visual Basic)](../../../visual-basic/language-reference/statements/synclock-statement.md) diff --git a/docs/standard/threading/how-to-use-spinlock-for-low-level-synchronization.md b/docs/standard/threading/how-to-use-spinlock-for-low-level-synchronization.md index 164fb75e828dd..b43ac11259bac 100644 --- a/docs/standard/threading/how-to-use-spinlock-for-low-level-synchronization.md +++ b/docs/standard/threading/how-to-use-spinlock-for-low-level-synchronization.md @@ -25,5 +25,5 @@ The following example demonstrates how to use a ## See also - [Threading objects and features](threading-objects-and-features.md) -- [lock statement (C#)](../../csharp/language-reference/keywords/lock-statement.md) +- [lock statement (C#)](../../csharp/language-reference/statements/lock.md) - [SyncLock statement (Visual Basic)](../../visual-basic/language-reference/statements/synclock-statement.md) diff --git a/docs/standard/threading/managed-threading-best-practices.md b/docs/standard/threading/managed-threading-best-practices.md index 150de99b405f4..2790ebc6efa99 100644 --- a/docs/standard/threading/managed-threading-best-practices.md +++ b/docs/standard/threading/managed-threading-best-practices.md @@ -94,7 +94,7 @@ Use the pr - 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. -- 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/keywords/lock-statement.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 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 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 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. diff --git a/docs/standard/threading/overview-of-synchronization-primitives.md b/docs/standard/threading/overview-of-synchronization-primitives.md index 92993df29642d..37dc72509b2f3 100644 --- a/docs/standard/threading/overview-of-synchronization-primitives.md +++ b/docs/standard/threading/overview-of-synchronization-primitives.md @@ -52,7 +52,7 @@ You can coordinate the interaction of threads that acquire a lock on the same ob For more information, see the API reference. > [!NOTE] -> Use the [lock](../../csharp/language-reference/keywords/lock-statement.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 class directly. Those statements are implemented by using the and 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 class directly. Those statements are implemented by using the and methods and a `try…finally` block to ensure that the acquired lock is always released. ### Mutex class diff --git a/docs/standard/threading/synchronizing-data-for-multithreading.md b/docs/standard/threading/synchronizing-data-for-multithreading.md index 2020bed5eed62..310ce9226f922 100644 --- a/docs/standard/threading/synchronizing-data-for-multithreading.md +++ b/docs/standard/threading/synchronizing-data-for-multithreading.md @@ -57,7 +57,7 @@ When multiple threads can make calls to the properties and methods of a single o ### Compiler support - Both Visual Basic and C# support a language keyword that uses and to lock the object. Visual Basic supports the [SyncLock](../../visual-basic/language-reference/statements/synclock-statement.md) statement; C# supports the [lock](../../csharp/language-reference/keywords/lock-statement.md) statement. + Both Visual Basic and C# support a language keyword that uses and to lock the object. Visual Basic supports the [SyncLock](../../visual-basic/language-reference/statements/synclock-statement.md) statement; C# supports the [lock](../../csharp/language-reference/statements/lock.md) statement. In both cases, if an exception is thrown in the code block, the lock acquired by the **lock** or **SyncLock** is released automatically. The C# and Visual Basic compilers emit a **try**/**finally** block with **Monitor.Enter** at the beginning of the try, and **Monitor.Exit** in the **finally** block. If an exception is thrown inside the **lock** or **SyncLock** block, the **finally** handler runs to allow you to do any clean-up work. @@ -71,4 +71,4 @@ In .NET Framework and Xamarin applications only, you can use the