Skip to content

Commit

Permalink
Add doc for analyzer CA1839 and CA1840
Browse files Browse the repository at this point in the history
  • Loading branch information
buyaa-n committed Nov 23, 2021
1 parent 4f55fb1 commit f768db8
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 0 deletions.
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 `Environment.ProcessPath`.

## Rule description

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

- It allocates a <xref:System.Diagnostics.Process> and <xref:System.Diagnostics.ProcessModule> instances, 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 the above and produces the same information.

> [!NOTE]
> **System.Environment.ProcessPath** is available starting from .NET 6.0.
## 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
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
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 a <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 `Environment.CurrentManagedThreadId`.

## Rule description

`Environment.CurrentManagedThreadId` is more compact and efficient replacement of `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
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
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 replacement of `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 replacement of `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

0 comments on commit f768db8

Please sign in to comment.