From 361790f1f4a4db508822a505127a5a7fc9f79f3c Mon Sep 17 00:00:00 2001 From: Dennis Doomen Date: Wed, 25 Mar 2026 07:12:35 -0700 Subject: [PATCH 1/3] Update AV1820 guideline Split from #298. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- _rules/1580.md | 6 ++++-- _rules/1820.md | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/_rules/1580.md b/_rules/1580.md index cb1b8b13..237716fb 100644 --- a/_rules/1580.md +++ b/_rules/1580.md @@ -4,10 +4,12 @@ rule_category: maintainability title: Write code that is easy to debug severity: 2 --- -Because debugger breakpoints cannot be set inside expressions, avoid overuse of nested method calls. For example, a line like: +Because debugger breakpoints cannot be set inside expressions, avoid overuse of nested method calls. For example, in some IDEs, a line like: string result = ConvertToXml(ApplyTransforms(ExecuteQuery(GetConfigurationSettings(source)))); requires extra steps to inspect intermediate method return values. On the other hard, were this expression broken into intermediate variables, setting a breakpoint on one of them would be sufficient. -**Note** This does not apply to chaining method calls, which is a common pattern in fluent APIs. +**Note:** This does not apply to chaining method calls, which is a common pattern in fluent APIs. + +**Tip:** [JetBrains Rider](https://www.jetbrains.com/rider/) has a very advanced debugger that allows you to choose into which part of a nested or chained call you want to step. It also displays all intermediate parameter and return values. diff --git a/_rules/1820.md b/_rules/1820.md index 0d2fc1d9..469c2fbd 100644 --- a/_rules/1820.md +++ b/_rules/1820.md @@ -1,7 +1,9 @@ --- rule_id: 1820 rule_category: performance -title: Only use `async` for low-intensive long-running activities +title: Only use `async`/`await` for I/O-bound or long-running activities severity: 1 --- -The usage of `async` won't automagically run something on a worker thread like `Task.Run` does. It just adds the necessary logic to allow releasing the current thread, and marshal the result back on that same thread if a long-running asynchronous operation has completed. In other words, use `async` only for I/O bound operations. +The usage of `async` won't automagically run something on a worker thread like `Task.Run` does. It just adds the necessary logic to allow releasing the current thread, and marshal the result back on that same thread if a long-running asynchronous operation has completed. In other words, use `async` only for I/O-bound operations. + +**Exception:** Tasks returned from `Task.Run` (which starts a background operation in parallel) can eventually be awaited to obtain their results, or passed to a method like `Task.WhenAll` that is awaited. From 60c5e27b38dbc62d31c632e29142ec9340443411 Mon Sep 17 00:00:00 2001 From: Dennis Doomen Date: Sun, 19 Apr 2026 08:44:45 +0200 Subject: [PATCH 2/3] Remove changes to rule AV1580 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- _rules/1580.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/_rules/1580.md b/_rules/1580.md index 237716fb..cb1b8b13 100644 --- a/_rules/1580.md +++ b/_rules/1580.md @@ -4,12 +4,10 @@ rule_category: maintainability title: Write code that is easy to debug severity: 2 --- -Because debugger breakpoints cannot be set inside expressions, avoid overuse of nested method calls. For example, in some IDEs, a line like: +Because debugger breakpoints cannot be set inside expressions, avoid overuse of nested method calls. For example, a line like: string result = ConvertToXml(ApplyTransforms(ExecuteQuery(GetConfigurationSettings(source)))); requires extra steps to inspect intermediate method return values. On the other hard, were this expression broken into intermediate variables, setting a breakpoint on one of them would be sufficient. -**Note:** This does not apply to chaining method calls, which is a common pattern in fluent APIs. - -**Tip:** [JetBrains Rider](https://www.jetbrains.com/rider/) has a very advanced debugger that allows you to choose into which part of a nested or chained call you want to step. It also displays all intermediate parameter and return values. +**Note** This does not apply to chaining method calls, which is a common pattern in fluent APIs. From 5d0151df87d4ab1f3927d656d0360ad8d5e500e1 Mon Sep 17 00:00:00 2001 From: Dennis Doomen Date: Sun, 3 May 2026 17:50:05 +0200 Subject: [PATCH 3/3] Update _rules/1820.md Co-authored-by: Bart Koelman <10324372+bkoelman@users.noreply.github.com> --- _rules/1820.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_rules/1820.md b/_rules/1820.md index 469c2fbd..f94fab32 100644 --- a/_rules/1820.md +++ b/_rules/1820.md @@ -4,6 +4,6 @@ rule_category: performance title: Only use `async`/`await` for I/O-bound or long-running activities severity: 1 --- -The usage of `async` won't automagically run something on a worker thread like `Task.Run` does. It just adds the necessary logic to allow releasing the current thread, and marshal the result back on that same thread if a long-running asynchronous operation has completed. In other words, use `async` only for I/O-bound operations. +The use of `async`/`await` won't automagically run something on a worker thread as `Task.Run` does. It just suspends execution at the await point and resumes execution after the task has completed. In other words, use `async`/`await` only for I/O-bound operations. **Exception:** Tasks returned from `Task.Run` (which starts a background operation in parallel) can eventually be awaited to obtain their results, or passed to a method like `Task.WhenAll` that is awaited.