Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add doc for analyzers CA1839 and CA1840 #27249

Merged
merged 3 commits into from
Nov 24, 2021
Merged
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
106 changes: 106 additions & 0 deletions docs/fundamentals/code-analysis/quality-rules/ca1839.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
title: "CA1839: Use 'Environment.ProcessPath'"
description: "'Environment.ProcessPath' is simpler and faster than 'Process.GetCurrentProcess().MainModule.FileName'."
ms.date: 11/23/2021
ms.topic: reference
f1_keywords:
- "CA1839"
helpviewer_keywords:
- "CA1839"
author: buyaa-n
dev_langs:
- CSharp
- VB
---

# CA1839: Use Environment.ProcessPath instead of Process.GetCurrentProcess().MainModule.FileName

| | Value |
|-|-|
| **Rule ID** |CA1839|
| **Category** |[Performance](performance-warnings.md)|
| **Fix is breaking or non-breaking** |Non-breaking|

## Cause

Using `Process.GetCurrentProcess().MainModule.FileName` for getting the path to the file that launched the process instead of <xref:System.Environment.ProcessPath?displayProperty=nameWithType>.

## Rule description

`System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName` is expensive:

- It allocates a <xref:System.Diagnostics.Process> and <xref:System.Diagnostics.ProcessModule> instance, usually just to get the `FileName`.
- The <xref:System.Diagnostics.Process> instance needs to be disposed, which has a performance impact.
- It's easy to forget to call <xref:System.Diagnostics.Process.Dispose> on the <xref:System.Diagnostics.Process> instance.
- If nothing else besides `FileName` uses the `Process` instance, then the linked size grows unnecessarily by increasing the graph of types referenced.
- It is somewhat difficult to discover or find this API.

`System.Environment.ProcessPath` avoids all of these downsides and produces the same information.

> [!NOTE]
> <xref:System.Environment.ProcessPath?displayProperty=fullName> is available starting in .NET 6.

## How to fix violations

The violation can either be fixed manually, or, in some cases, using Quick Actions to fix code in Visual Studio.

The following two code snippets show a violation of the rule and how to fix it:

```csharp
using System.Diagnostics;

class MyClass
{
void MyMethod()
{
string path = Process.GetCurrentProcess().MainModule.FileName; // Violation occurs
}
}
```

```vb
Imports System.Diagnostics

Class MyClass
Private Sub MyMethod()
Dim path As String = Process.GetCurrentProcess().MainModule.FileName ' Violation occurs.
End Function
End Class
```

```csharp
using System.Diagnostics;

class MyClass
{
void MyMethod()
{
string path = System.Environment.ProcessPath; // Violation fixed
}
}
```

```vb
Imports System.Diagnostics

Class MyClass
Private Sub MyMethod()
Dim path As String = System.Environment.ProcessPath ' Violation fixed.
End Function
End Class
```

> [!TIP]
> A code fix is available for this rule in Visual Studio. To use it, position the cursor on the violation and press **Ctrl**+**.** (period). Choose **Use 'Environment.ProcessPath'** from the list of options that's presented.
>
> ![Code fix for CA1839 - Use 'Environment.ProcessPath'](media/ca1839-codefix.png)

## When to suppress warnings

It's safe to suppress a violation of this rule if you're not concerned about the performance impact from unnecessary allocation and eventual disposal of the <xref:System.Diagnostics.Process> and <xref:System.Diagnostics.ProcessModule> instances.

## See also

- [Performance rules](performance-warnings.md)
- [Use 'Environment.ProcessId' instead of 'Process.GetCurrentProcess().Id'](ca1837.md)
- [Use 'Environment.CurrentManagedThreadId' instead of 'Thread.CurrentThread.ManagedThreadId'](ca1840.md)
95 changes: 95 additions & 0 deletions docs/fundamentals/code-analysis/quality-rules/ca1840.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
---
title: "CA1840: Use 'Environment.CurrentManagedThreadId'"
description: "'Environment.CurrentManagedThreadId' is simpler and faster than 'Thread.CurrentThread.ManagedThreadId'."
ms.date: 11/23/2021
ms.topic: reference
f1_keywords:
- "CA1840"
helpviewer_keywords:
- "CA1840"
author: buyaa-n
dev_langs:
- CSharp
- VB
---

# CA1840: Use Environment.CurrentManagedThreadId instead of Thread.CurrentThread.ManagedThreadId

| | Value |
|-|-|
| **Rule ID** |CA1840|
| **Category** |[Performance](performance-warnings.md)|
| **Fix is breaking or non-breaking** |Non-breaking|

## Cause

Using `Thread.CurrentThread.ManagedThreadId` for getting the current managed thread ID instead of <xref:System.Environment.CurrentManagedThreadId?displayProperty=fullName>.

## Rule description

<xref:System.Environment.CurrentManagedThreadId?displayProperty=fullName> is a compact and efficient replacement of the `Thread.CurrentThread.ManagedThreadId` pattern.

## How to fix violations

The violation can either be fixed manually, or, in some cases, using Quick Actions to fix code in Visual Studio.

The following two code snippets show a violation of the rule and how to fix it:

```csharp
using System.Threading;

class MyClass
{
void MyMethod()
{
int id = Thread.CurrentThread.ManagedThreadId; // Violation occurs
}
}
```

```vb
Imports System.Threading

Class MyClass
Private Sub MyMethod()
Dim id As Integer = Thread.CurrentThread.ManagedThreadId ' Violation occurs.
End Function
End Class
```

```csharp
using System.Threading;

class MyClass
{
void MyMethod()
{
int id = System.Environment.CurrentManagedThreadId; // Violation fixed
}
}
```

```vb
Imports System.Threading

Class MyClass
Private Sub MyMethod()
Dim id As Integer = System.Environment.CurrentManagedThreadId ' Violation fixed.
End Function
End Class
```

> [!TIP]
> A code fix is available for this rule in Visual Studio. To use it, position the cursor on the violation and press **Ctrl**+**.** (period). Choose **Use 'Environment.CurrentManagedThreadId'** from the list of options that's presented.
>
> ![Code fix for CA1840 - Use 'Environment.CurrentManagedThreadId'](media/ca1840-codefix.png)

## When to suppress warnings

It's safe to suppress a violation of this rule if you're not concerned about the performance impact from using `Thread.CurrentThread.ManagedThreadId`.

## See also

- [Performance rules](performance-warnings.md)
- [Use 'Environment.ProcessId' instead of 'Process.GetCurrentProcess().Id'](ca1837.md)
- [Use 'Environment.ProcessPath' instead of 'Process.GetCurrentProcess().MainModule.FileName'](ca1839.md)
2 changes: 2 additions & 0 deletions docs/fundamentals/code-analysis/quality-rules/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ The following table lists code quality analysis rules.
> |[CA1836: Prefer `IsEmpty` over `Count` when available](ca1836.md) | Prefer `IsEmpty` property that is more efficient than `Count`, `Length`, <xref:System.Linq.Enumerable.Count%60%601%28System.Collections.Generic.IEnumerable%7B%60%600%7D%29> or <xref:System.Linq.Enumerable.LongCount%60%601%28System.Collections.Generic.IEnumerable%7B%60%600%7D%29> to determine whether the object contains or not any items. |
> | [CA1837: Use `Environment.ProcessId` instead of `Process.GetCurrentProcess().Id`](ca1837.md) | `Environment.ProcessId` is simpler and faster than `Process.GetCurrentProcess().Id`. |
> | [CA1838: Avoid `StringBuilder` parameters for P/Invokes](ca1838.md) | Marshaling of 'StringBuilder' always creates a native buffer copy, resulting in multiple allocations for one marshaling operation. |
> | [CA1839: Use Environment.ProcessPath instead of Process.GetCurrentProcess().MainModule.FileName](ca1837.md) | `Environment.ProcessPath` is simpler and faster than `Process.GetCurrentProcess().MainModule.FileName`. |
> | [CA1840: Use Environment.CurrentManagedThreadId instead of Thread.CurrentThread.ManagedThreadId](ca1837.md) | `Environment.CurrentManagedThreadId` is more compact and efficient than `Thread.CurrentThread.ManagedThreadId`. |
> | [CA1841: Prefer Dictionary Contains methods](ca1841.md) | Calling `Contains` on the `Keys` or `Values` collection may often be more expensive than calling `ContainsKey` or `ContainsValue` on the dictionary itself. |
> | [CA1844: Provide memory-based overrides of async methods when subclassing 'Stream'](ca1844.md) | To improve performance, override the memory-based async methods when subclassing 'Stream'. Then implement the array-based methods in terms of the memory-based methods. |
> | [CA1845: Use span-based 'string.Concat'](ca1845.md) | It is more efficient to use `AsSpan` and `string.Concat`, instead of `Substring` and a concatenation operator. |
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ Performance rules support high-performance libraries and applications.
| [CA1836: Prefer `IsEmpty` over `Count` when available](ca1836.md) | Prefer `IsEmpty` property that is more efficient than `Count`, `Length`, <xref:System.Linq.Enumerable.Count%60%601%28System.Collections.Generic.IEnumerable%7B%60%600%7D%29> or <xref:System.Linq.Enumerable.LongCount%60%601%28System.Collections.Generic.IEnumerable%7B%60%600%7D%29> to determine whether the object contains or not any items. |
| [CA1837: Use `Environment.ProcessId` instead of `Process.GetCurrentProcess().Id`](ca1837.md) | `Environment.ProcessId` is simpler and faster than `Process.GetCurrentProcess().Id`. |
| [CA1838: Avoid `StringBuilder` parameters for P/Invokes](ca1838.md) | Marshaling of `StringBuilder` always creates a native buffer copy, resulting in multiple allocations for one marshaling operation. |
| [CA1839: Use Environment.ProcessPath instead of Process.GetCurrentProcess().MainModule.FileName](ca1837.md) | `Environment.ProcessPath` is simpler and faster than `Process.GetCurrentProcess().MainModule.FileName`. |
| [CA1840: Use Environment.CurrentManagedThreadId instead of Thread.CurrentThread.ManagedThreadId](ca1837.md) | `Environment.CurrentManagedThreadId` is more compact and efficient than `Thread.CurrentThread.ManagedThreadId`. |
| [CA1841: Prefer Dictionary Contains methods](ca1841.md) | Calling `Contains` on the `Keys` or `Values` collection may often be more expensive than calling `ContainsKey` or `ContainsValue` on the dictionary itself. |
| [CA1844: Provide memory-based overrides of async methods when subclassing 'Stream'](ca1844.md) | To improve performance, override the memory-based async methods when subclassing 'Stream'. Then implement the array-based methods in terms of the memory-based methods. |
| [CA1845: Use span-based 'string.Concat'](ca1845.md) | It is more efficient to use `AsSpan` and `string.Concat`, instead of `Substring` and a concatenation operator. |
Expand Down
4 changes: 4 additions & 0 deletions docs/fundamentals/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -986,6 +986,10 @@ items:
href: code-analysis/quality-rules/ca1837.md
- name: CA1838
href: code-analysis/quality-rules/ca1838.md
- name: CA1839
href: code-analysis/quality-rules/ca1839.md
- name: CA1840
href: code-analysis/quality-rules/ca1840.md
- name: CA1841
href: code-analysis/quality-rules/ca1841.md
- name: CA1844
Expand Down