diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 9db9b7e52f184..589acee7efef8 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,45 +1,59 @@ -When you're assigned an issue, after you've completed your work and the workflows (status checks) have run, check to make sure there are no build warnings under the OpenPublishing.Build status check. If there are, open the build report (under View Details) and resolve any build warnings you introduced. - -When writing documentation, follow the following guidelines: - -Unless otherwise specified, all .NET content refers to modern .NET (not .NET Framework). - -Follow the style of the [Microsoft Writing Style Guide](https://learn.microsoft.com/en-us/style-guide/welcome/). - -Headings should be in sentence case, not title case. Don't use gerunds in titles. - -Use the active voice whenever possible, and second person to address the reader directly. - -Use a conversational tone with contractions. - -Be concise. - -Break up long sentences. - -Use the present tense for instructions and descriptions. For example, "The method returns a value" instead of "The method will return a value." - -Do not use "we" or "our" to refer to the authors of the documentation. - -Use the imperative mood for instructions. For example, "Call the method" instead of "You should call the method." - -Use "might" instead of "may" to indicate possibility. For example, "This method might throw an exception" instead of "This method may throw an exception." - -Use the Oxford comma in lists of three or more items. - -Number ordered list items all as "1." instead of "1.", "2.", etc. - -Use bullets for unordered lists. Unless *all* the bullet list items are three words or less, each bullet item should end with a period. - -Use **bold** when referring to UI elements. Use `code style` for file names and folders, custom types, and other text that should never be localized. - -Put raw URLs within angle brackets. - -Include links to related topics and resources where appropriate. Use relative links if the target file lives in this repo. If you add a link to another page on learn.microsoft.com that's not in this repo, remove https://learn.microsoft.com/en-us from the link. - -When mentioning APIs, use cross-references to the API documentation. These links are formatted as . You can find the API doc ID in the XML files in the https://github.com/dotnet/dotnet-api-docs repository. For types, the doc ID is the value of the `Value` attribute of the `` element where the `Language` attribute value is `DocId`. For other (member) APIs, the doc ID is the value of the `Value` attribute of the `` element where the `Language` attribute value is `DocId`. Omit the first two characters of the DocId. For example, the xref link for System.String is . - -If you're assigned a GitHub issue that's labeled "breaking-change", include the prompt directions in the .github/prompts/breaking-change.md file in this repo. - -If you include a code snippet that's more than 6 lines long, put it in a separate .cs file in a folder named "snippets" in the same folder as the document. Within the "snippets" folder, add a new directory with the name of the document. For example, if the document is named "my-doc.md", create a folder named "snippets/my-doc" folder. Also add a simple .csproj file to the same directory that targets the latest version of .NET. It can be a library or executable project. - -If you're adding a new Markdown file, it should be named in all lowercase with hyphens separating words. Also, omit any filler words such as "the" or "a" from the file name. +# .NET Documentation Guidelines + +## Terminology +- Unless otherwise specified, all .NET content refers to modern .NET (not .NET Framework). + +## Writing Style +Follow [Microsoft Writing Style Guide](https://learn.microsoft.com/en-us/style-guide/welcome/) with these specifics: + +### Voice and Tone +- Active voice, second person addressing reader directly. +- Conversational tone with contractions. +- Present tense for instructions/descriptions. +- Imperative mood for instructions ("Call the method" not "You should call the method"). +- Use "might" instead of "may" for possibility. +- Use "can" instead of "may" for permissible actions. +- Avoid "we"/"our" referring to documentation authors or product teams. + +### Structure and Format +- Sentence case headings (no gerunds in titles). +- Be concise, break up long sentences. +- Oxford comma in lists. +- Number all ordered list items as "1." (not sequential numbering like "1.", "2.", "3.", etc.) +- Use bullets for unordered lists. +- Ordered and unordered lists should use complete sentences with proper punctuation, ending with a period if it's more than three words. +- Avoid "etc." or "and so on" - provide complete lists or use "for example". +- No consecutive headings without content between them. + +### Formatting Conventions +- **Bold** for UI elements. +- `Code style` for file names, folders, custom types, non-localizable text. +- Raw URLs in angle brackets. +- Use relative links for files in this repo. +- Remove `https://learn.microsoft.com/en-us` from learn.microsoft.com links. + +## API References +Use cross-references: ``. + +To find API doc IDs: +1. Check XML files in https://github.com/dotnet/dotnet-api-docs. +2. For types: `Value` attribute of `` where `Language="DocId"` (omit first 2 characters). +3. For members: `Value` attribute of `` where `Language="DocId"` (omit first 2 characters). + +If unsure, use API browser: `https://learn.microsoft.com/api/apibrowser/dotnet/search?api-version=0.2&locale=en-us&search={API_NAME}&$skip=0&$top=5` and then use the `url` value from the results as a manual link. + +## Code Snippets +For snippets >6 lines: +1. Create `./snippets/my-doc/language` folder in same directory as document (for a document named `my-doc.md`) where language is either vb (for visual basic) or csharp (for c#). Omit the `language` component when the document is in the `docs/visual-basic`, `docs/csharp`, or `docs/fsharp` folders. +1. Add snippet as separate code file. +1. Include simple project file targeting latest .NET. +1. All code should use the latest stable versions/features. +1. Create examples in both C# and Visual Basic unless the article referencing the snippet resides in the in the `csharp`, `fsharp`, and `visual-basic` language folders. +1. When you add code, use code comments sparingly because they don't get localized. You can use them to briefly clarify code-specific details (such as logic, parameters, or edge cases). Put any critical information and context in the markdown text of the referencing article. + +## File Naming +New Markdown files: lowercase with hyphens, omit filler words (the, a, etc.). + +## Special Cases +- Breaking changes: Include directions from `.github/prompts/breaking-change.md`. +- When you (Copilot) are assigned an issue in GitHub, after you've completed your work and the workflows (status checks) have run, check to make sure there are no build warnings under the OpenPublishing.Build status check. If there are, open the build report (under View Details) and resolve any build warnings you introduced. diff --git a/docfx.json b/docfx.json index 98faf97e13af3..a4a2fa1fc0dae 100644 --- a/docfx.json +++ b/docfx.json @@ -362,8 +362,8 @@ "docs/core/project-sdk/**/**.md": "gewarren", "docs/core/runtime-config/**/**.md": "gewarren", "docs/core/testing/**/**.md": "IEvangelist", - "docs/core/tools/**/**.md": "tdykstra", - "docs/core/tutorials/**/**.md": "tdykstra", + "docs/core/tools/**/**.md": "adegeo", + "docs/core/tutorials/**/**.md": "billwagner", "docs/core/versions/**/**.md": "billwagner", "docs/core/whats-new/**/**.md": "gewarren", "docs/csharp/**/*.*": "billwagner", @@ -408,7 +408,7 @@ "docs/standard/attributes/**/**.md": "gewarren", "docs/standard/base-types/**/**.md": "adegeo", "docs/standard/collections/**/**.md": "IEvangelist", - "docs/standard/commandline/**/**.md": "tdykstra", + "docs/standard/commandline/**/**.md": "gewarren", "docs/standard/data/**/**.md": "gewarren", "docs/standard/data/sqlite/**/**.md": "ajcvickers", "docs/standard/datetime/**/**.md": "adegeo", @@ -455,8 +455,8 @@ "docs/core/project-sdk/**/**.md": "gewarren", "docs/core/runtime-config/**/**.md": "gewarren", "docs/core/testing/**/**.md": "dapine", - "docs/core/tools/**/**.md": "tdykstra", - "docs/core/tutorials/**/**.md": "tdykstra", + "docs/core/tools/**/**.md": "adegeo", + "docs/core/tutorials/**/**.md": "wiwagn", "docs/core/versions/**/**.md": "wiwagn", "docs/core/whats-new/**/**.md": "gewarren", "docs/csharp/**/*.*": "wiwagn", @@ -496,7 +496,7 @@ "docs/standard/attributes/**/**.md": "gewarren", "docs/standard/base-types/**/**.md": "adegeo", "docs/standard/collections/**/**.md": "dapine", - "docs/standard/commandline/**/**.md": "tdykstra", + "docs/standard/commandline/**/**.md": "gewarren", "docs/standard/data/**/**.md": "gewarren", "docs/standard/datetime/**/**.md": "adegeo", "docs/standard/design-guidelines/**/**.md": "kcwalina", diff --git a/docs/core/compatibility/10.0.md b/docs/core/compatibility/10.0.md index 1dde5f41d1b7a..fb0e411ae0e0f 100644 --- a/docs/core/compatibility/10.0.md +++ b/docs/core/compatibility/10.0.md @@ -129,4 +129,5 @@ If you're migrating an app to .NET 10, the breaking changes listed here might af | Title | Type of change | Introduced version | |-------|---------------------------------------|--------------------| +| [Empty ColumnDefinitions and RowDefinitions are disallowed](wpf/10.0/empty-grid-definitions.md) | Source incompatible | Preview 5 | | [Incorrect usage of DynamicResource causes application crash](wpf/10.0/dynamicresource-crash.md) | Source incompatible/behavioral change | Preview 4 | diff --git a/docs/core/compatibility/toc.yml b/docs/core/compatibility/toc.yml index c4574a3003604..264f6a530f18a 100644 --- a/docs/core/compatibility/toc.yml +++ b/docs/core/compatibility/toc.yml @@ -144,6 +144,8 @@ items: href: windows-forms/10.0/statusstrip-renderer.md - name: WPF items: + - name: Empty ColumnDefinitions and RowDefinitions are disallowed + href: wpf/10.0/empty-grid-definitions.md - name: Incorrect usage of DynamicResource causes application crash href: wpf/10.0/dynamicresource-crash.md - name: .NET 9 diff --git a/docs/core/compatibility/wpf/10.0/empty-grid-definitions.md b/docs/core/compatibility/wpf/10.0/empty-grid-definitions.md new file mode 100644 index 0000000000000..22fcd1e2983af --- /dev/null +++ b/docs/core/compatibility/wpf/10.0/empty-grid-definitions.md @@ -0,0 +1,64 @@ +--- +title: "Breaking change - Empty ColumnDefinitions and RowDefinitions are disallowed" +description: "Learn about the breaking change in WPF in .NET 10 where empty Grid.ColumnDefinitions or Grid.RowDefinitions declarations now cause MC3063 compilation errors." +ms.date: 08/11/2025 +ai-usage: ai-assisted +ms.custom: https://github.com/dotnet/docs/issues/47743 +--- + +# Empty ColumnDefinitions and RowDefinitions are disallowed + +Starting with .NET 10, WPF applications fail to build if `` or `` are declared but left empty in XAML. This results in error `MC3063`, which indicates that the property doesn't have a value. + +## Version introduced + +.NET 10 Preview 5 + +## Previous behavior + +Previously, WPF applications with empty `` or `` compiled successfully, even though the layout definitions were incomplete. The layout defaulted to a single row and column, placing all child elements in that single cell unless otherwise specified. + +Example that previously compiled: + +```xml + + + + +``` + +## New behavior + +Starting in .NET 10, the same code now fails to compile with the following error: + +```output +error MC3063: Property 'ColumnDefinitions' does not have a value. +``` + +This occurs when `` or `` elements are declared but contain no child `` or `` elements. + +## Type of breaking change + +This change can affect [source compatibility](../../categories.md#source-compatibility). + +## Reason for change + +This change is a direct consequence of implementing Grid XAML Shorthand Syntax support. + +## Recommended action + +Ensure that all `` and `` contains at least one valid or element. + +Corrected example: + +```xml + + + + + +``` + +## Affected APIs + +None. diff --git a/docs/core/diagnostics/built-in-metrics-diagnostics.md b/docs/core/diagnostics/built-in-metrics-diagnostics.md index d4e443fc5e210..e51329efa0566 100644 --- a/docs/core/diagnostics/built-in-metrics-diagnostics.md +++ b/docs/core/diagnostics/built-in-metrics-diagnostics.md @@ -26,42 +26,42 @@ You can enable these metrics by calling the | `{report}` | Number of times a health report reported the health status of an application. | -| Attribute | Type | Description | Examples | Presence | -|---|---|---|---|---| -| `dotnet.health_check.status` | string | The health status of an application. | `Healthy`; `Unhealthy` | Always | +| Attribute | Type | Description | Examples | Presence | +|------------------------------|----------|--------------------------------------|------------------------|----------| +| `dotnet.health_check.status` | `string` | The health status of an application. | `Healthy`; `Unhealthy` | Always | `dotnet.health_check.status` is one of the following: -| Value | Description | -|---|---| -| `Degraded` | An application was in degraded state. | -| `Healthy` | An application was healthy. | -| `Unhealthy` | An application was unhealthy. | +| Value | Description | +|-------------|---------------------------------------| +| `Degraded` | An application was in degraded state. | +| `Healthy` | An application was healthy. | +| `Unhealthy` | An application was unhealthy. | -Available starting in: .NET 8.0. +Available starting in: .NET 8. ##### Metric: `dotnet.health_check.unhealthy_checks` | Name | Instrument Type | Unit (UCUM) | Description | | ---- | --------------- | ----------- | ----------- | -| `dotnet.health_check.unhealthy_checks` | Counter | `{unhealthy_check}` | Number of times a health check reported the health status of an application as `Degraded` or `Unhealthy`. | +| `dotnet.health_check.unhealthy_checks` | | `{unhealthy_check}` | Number of times a health check reported the health status of an application as `Degraded` or `Unhealthy`. | -| Attribute | Type | Description | Examples | Presence | -|---|---|---|---|---| -| `dotnet.health_check.name` | string | The name of the health check. | `ApplicationLifecycle` | Always | -| `dotnet.health_check.status` | string | The health status of an application. | `Healthy`; `Unhealthy` | Always | +| Attribute | Type | Description | Examples | Presence | +|------------------------------|----------|--------------------------------------|------------------------|----------| +| `dotnet.health_check.name` | `string` | The name of the health check. | `ApplicationLifecycle` | Always | +| `dotnet.health_check.status` | `string` | The health status of an application. | `Healthy`; `Unhealthy` | Always | `dotnet.health_check.status` is one of the following: -| Value | Description | -|---|---| -| `Degraded` | An application was in degraded state. | -| `Healthy` | An application was healthy. | -| `Unhealthy` | An application was unhealthy. | +| Value | Description | +|-------------|---------------------------------------| +| `Degraded` | An application was in degraded state. | +| `Healthy` | An application was healthy. | +| `Unhealthy` | An application was unhealthy. | -Available starting in: .NET 8.0. +Available starting in: .NET 8. ## `Microsoft.Extensions.Diagnostics.ResourceMonitoring` @@ -85,9 +85,9 @@ The instrument is only available on a system running on containers both on Windo | Name | Instrument Type | Unit (UCUM) | Description | | ---- | --------------- | ----------- | ----------- | -| `container.cpu.limit.utilization` | ObservableGauge | `1` | The CPU consumption of the running containerized application relative to resource limit in range `[0, 1]`. | +| `container.cpu.limit.utilization` | | `1` | The CPU consumption of the running containerized application relative to resource limit in range `[0, 1]`. | -Available starting in: .NET 8.8.0. +Available starting in `Microsoft.Extensions.Diagnostics.ResourceMonitoring` 8.8.0. ##### Metric: `container.cpu.request.utilization` @@ -95,9 +95,9 @@ The instrument is only available on a system running on containers on Linux. | Name | Instrument Type | Unit (UCUM) | Description | | ---- | --------------- | ----------- | ----------- | -| `container.cpu.request.utilization` | ObservableGauge | `1` | The CPU consumption of the running containerized application relative to resource request in range `[0, 1]`. | +| `container.cpu.request.utilization` | | `1` | The CPU consumption of the running containerized application relative to resource request in range `[0, 1]`. | -Available starting in: .NET 8.8.0. +Available starting in `Microsoft.Extensions.Diagnostics.ResourceMonitoring` 8.8.0. ##### Metric: `container.cpu.time` @@ -105,9 +105,9 @@ The instrument is only available on a system running on a container either on Wi | Name | Instrument Type | Unit (UCUM) | Description | | ---- | --------------- | ----------- | ----------- | -| `container.cpu.time` | ObservableCounter | `s` | CPU time used by the container. | +| `container.cpu.time` | | `s` | CPU time used by the container. | -Available starting in: .NET 9.8.0. +Available starting in `Microsoft.Extensions.Diagnostics.ResourceMonitoring` 9.8.0. ##### Metric: `container.memory.limit.utilization` @@ -115,9 +115,9 @@ The instrument is only available on a system running on containers both on Windo | Name | Instrument Type | Unit (UCUM) | Description | | ---- | --------------- | ----------- | ----------- | -| `container.memory.limit.utilization` | ObservableGauge | `1` | The memory consumption of the running containerized application relative to resource limit in range `[0, 1]`. | +| `container.memory.limit.utilization` | | `1` | The memory consumption of the running containerized application relative to resource limit in range `[0, 1]`. | -Available starting in: .NET 8.8.0. +Available starting in `Microsoft.Extensions.Diagnostics.ResourceMonitoring` 8.8.0. ##### Metric: `container.memory.usage` @@ -125,35 +125,35 @@ The instrument is only available on a system running on containers either on Win | Name | Instrument Type | Unit (UCUM) | Description | | ---- | --------------- | ----------- | ----------- | -| `container.memory.usage` | ObservableUpDownCounter | `By` | Memory usage of all processes in the container measured in bytes. | +| `container.memory.usage` | | `By` | Memory usage of all processes in the container measured in bytes. | -Available starting in: .NET 9.8.0. +Available starting in `Microsoft.Extensions.Diagnostics.ResourceMonitoring` 9.8.0. ##### Metric: `process.cpu.utilization` | Name | Instrument Type | Unit (UCUM) | Description | | ---- | --------------- | ----------- | ----------- | -| `process.cpu.utilization` | ObservableGauge | `1` | The CPU consumption of the running application in range `[0, 1]`. | +| `process.cpu.utilization` | | `1` | The CPU consumption of the running application in range `[0, 1]`. | -Available starting in: .NET 8.0. +Available starting in: .NET 8. ##### Metric: `dotnet.process.memory.virtual.utilization` | Name | Instrument Type | Unit (UCUM) | Description | | ---- | --------------- | ----------- | ----------- | -| `dotnet.process.memory.virtual.utilization` | ObservableGauge | `1` | The memory consumption of the running application in range `[0, 1]`. | +| `dotnet.process.memory.virtual.utilization` | | `1` | The memory consumption of the running application in range `[0, 1]`. | -Available starting in: .NET 8.0. +Available starting in: .NET 8. ##### Metric: `system.network.connections` | Name | Instrument Type | Unit (UCUM) | Description | | ---- | --------------- | ----------- | ----------- | -| `system.network.connections` | ObservableUpDownCounter | `{connection}` | Number of network connections by state. | +| `system.network.connections` | | `{connection}` | Number of network connections by state. | -| Attribute | Type | Description | Examples | Presence | -|---|---|---|---|---| -| `network.type` | string | OSI network layer or non-OSI equivalent. | `ipv4`; `ipv6` | Always | -| `system.network.state` | string | The state of a network connection. | `close`; `listen` | Always | +| Attribute | Type | Description | Examples | Presence | +|------------------------|----------|------------------------------------------|-------------------|----------| +| `network.type` | `string` | OSI network layer or non-OSI equivalent. | `ipv4`; `ipv6` | Always | +| `system.network.state` | `string` | The state of a network connection. | `close`; `listen` | Always | -Available starting in: .NET 8.0. +Available starting in: .NET 8. diff --git a/docs/core/diagnostics/built-in-metrics-runtime.md b/docs/core/diagnostics/built-in-metrics-runtime.md index fab4da8c6e4fc..df043f55e5b5e 100644 --- a/docs/core/diagnostics/built-in-metrics-runtime.md +++ b/docs/core/diagnostics/built-in-metrics-runtime.md @@ -11,7 +11,7 @@ This article describes the built-in metrics for .NET runtime libraries that are API. For a listing of metrics based on the older [EventCounters](event-counters.md) API, see [Available counters](available-counters.md). > [!TIP] -> For more information about how to collect and report these metrics, see [Collecting Metrics](metrics-collection.md). +> For more information about how to collect and report these metrics, see [Collecting metrics](metrics-collection.md). ## `System.Runtime` @@ -19,71 +19,71 @@ The `System.Runtime` Meter reports measurements from the GC, JIT, AssemblyLoader ##### Metric: `dotnet.process.cpu.time` -| Name | Instrument Type | Unit (UCUM) | Description | -| ---- | --------------- | ----------- | ----------- | -| `dotnet.process.cpu.time` | Counter | `s` | CPU time used by the process. | +| Name | Instrument Type | Unit (UCUM) | Description | +|---------------------------|---------------------------------------------|-------------|-------------------------------| +| `dotnet.process.cpu.time` | | `s` | CPU time used by the process. | -| Attribute | Type | Description | Examples | Presence | -|---|---|---|---|---| -| `cpu.mode` | string | The mode of the CPU. | `user`; `system` | Always | +| Attribute | Type | Description | Examples | Presence | +|------------|----------|----------------------|------------------|----------| +| `cpu.mode` | `string` | The mode of the CPU. | `user`; `system` | Always | This metric reports the same values as accessing the processor time properties on for the current process. The `system` mode corresponds to and `user` mode corresponds to -Available starting in: .NET 9.0. +Available starting in: .NET 9. ##### Metric: `dotnet.process.memory.working_set` | Name | Instrument Type | Unit (UCUM) | Description | | ---- | --------------- | ----------- | ----------- | -| `dotnet.process.memory.working_set` | UpDownCounter | `By` | The number of bytes of physical memory mapped to the process context. | +| `dotnet.process.memory.working_set` | | `By` | The number of bytes of physical memory mapped to the process context. | This metric reports the same values as calling property. -Available starting in: .NET 9.0. +Available starting in: .NET 9. ##### Metric: `dotnet.gc.collections` | Name | Instrument Type | Unit (UCUM) | Description | | ---- | --------------- | ----------- | ----------- | -| `dotnet.gc.collections` | Counter | `{collection}` | The number of garbage collections that have occurred since the process has started. | +| `dotnet.gc.collections` | | `{collection}` | The number of garbage collections that have occurred since the process has started. | | Attribute | Type | Description | Examples | Presence | |---|---|---|---|---| -| `gc.heap.generation` | string | Name of the maximum managed heap generation being collected. | `gen0`; `gen1`; `gen2` | Always | +| `gc.heap.generation` | `string` | Name of the maximum managed heap generation being collected. | `gen0`; `gen1`; `gen2` | Always | The .NET GC is a generational garbage collector. Each time the garbage collector runs, it uses heuristics to select a maximum generation and then collects objects in all generations up to the selected maximum. For example, a `gen1` collection collects all objects in generations 0 and 1. A `gen2` collection collects all objects in generations 0, 1, and 2. For more information about the .NET GC and generational garbage collection, see the [.NET garbage collection guide](../../standard/garbage-collection/fundamentals.md#generations). -Available starting in: .NET 9.0. +Available starting in: .NET 9. ##### Metric: `dotnet.gc.heap.total_allocated` | Name | Instrument Type | Unit (UCUM) | Description | | ---- | --------------- | ----------- | ----------- | -| `dotnet.gc.heap.total_allocated` | Counter | `By` | The *approximate* number of bytes allocated on the managed GC heap since the process started. The returned value does not include any native allocations. | +| `dotnet.gc.heap.total_allocated` | | `By` | The *approximate* number of bytes allocated on the managed GC heap since the process started. The returned value does not include any native allocations. | This metric reports the same values as calling . For more information about the .NET GC, see the [.NET garbage collection guide](../../standard/garbage-collection/fundamentals.md). -Available starting in: .NET 9.0. +Available starting in: .NET 9. ##### Metric: `dotnet.gc.last_collection.memory.committed_size` | Name | Instrument Type | Unit (UCUM) | Description | | ---- | --------------- | ----------- | ----------- | -| `dotnet.gc.last_collection.memory.committed_size` | UpDownCounter | `By` | The amount of committed virtual memory in use by the .NET GC, as observed during the latest garbage collection. | +| `dotnet.gc.last_collection.memory.committed_size` | | `By` | The amount of committed virtual memory in use by the .NET GC, as observed during the latest garbage collection. | This metric reports the same values as calling . Committed virtual memory may be larger than the heap size because it includes both memory for storing existing objects (the heap size) and some extra memory that is ready to handle newly allocated objects in the future. For more information about the .NET GC, see the [.NET garbage collection guide](../../standard/garbage-collection/fundamentals.md). -Available starting in: .NET 9.0. +Available starting in: .NET 9. ##### Metric: `dotnet.gc.last_collection.heap.size` | Name | Instrument Type | Unit (UCUM) | Description | | ---- | --------------- | ----------- | ----------- | -| `dotnet.gc.last_collection.heap.size` | UpDownCounter | `By` | The managed GC heap size (including fragmentation), as observed during the latest garbage collection. | +| `dotnet.gc.last_collection.heap.size` | | `By` | The managed GC heap size (including fragmentation), as observed during the latest garbage collection. | | Attribute | Type | Description | Examples | Presence | |---|---|---|---|---| -| `gc.heap.generation` | string | Name of the garbage collector managed heap generation. | `gen0`; `gen1`; `gen2`; `loh`; `poh` | Always | +| `gc.heap.generation` | `string` | Name of the garbage collector managed heap generation. | `gen0`; `gen1`; `gen2`; `loh`; `poh` | Always | The .NET GC divides the heap into generations. In addition to the standard numbered generations, the GC also puts some objects into two special generations: @@ -92,17 +92,17 @@ The .NET GC divides the heap into generations. In addition to the standard numbe Both of these special generations are collected during `gen2` GC collections. For more information about the .NET GC, see the [.NET Garbage collection guide](../../standard/garbage-collection/fundamentals.md). -Available starting in: .NET 9.0. +Available starting in: .NET 9. ##### Metric: `dotnet.gc.last_collection.heap.fragmentation.size` | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `dotnet.gc.last_collection.heap.fragmentation.size` | UpDownCounter | `By` | The heap fragmentation, as observed during the latest garbage collection. | +| `dotnet.gc.last_collection.heap.fragmentation.size` | | `By` | The heap fragmentation, as observed during the latest garbage collection. | -| Attribute | Type | Description | Examples | Presence | -|---|---|---|---|---| -| `gc.heap.generation` | string | Name of the garbage collector managed heap generation. | `gen0`; `gen1`; `gen2`; `loh`; `poh` | Always | +| Attribute | Type | Description | Examples | Presence | +|----------------------|----------|-------------|--------------------------------------|----------| +| `gc.heap.generation` | `string` | Name of the garbage collector managed heap generation. | `gen0`; `gen1`; `gen2`; `loh`; `poh` | Always | This metric reports the same values as calling . @@ -110,25 +110,25 @@ When .NET objects are allocated, initially they tend to be laid out contiguously For more information about how the .NET GC works, analyzing GC performance, and what role fragmentation plays, see [.NET memory performance analysis](https://github.com/Maoni0/mem-doc/blob/master/doc/.NETMemoryPerformanceAnalysis.md). -Available starting in: .NET 9.0. +Available starting in: .NET 9. ##### Metric: `dotnet.gc.pause.time` | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `dotnet.gc.pause.time` | Counter | `s` | The total amount of time paused in GC since the process started. | +| `dotnet.gc.pause.time` | | `s` | The total amount of time paused in GC since the process started. | This metric reports the same values as calling . Each time the .NET GC does a collection it needs to briefly pause all threads running managed code to determine which objects are still referenced. This metric reports the sum of all these pause times since the process began. You can use this metric to determine what fraction of time threads spend paused for GC versus the time they're able to run managed code. -Available starting in: .NET 9.0. +Available starting in: .NET 9. ##### Metric: `dotnet.jit.compiled_il.size` | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `dotnet.jit.compiled_il.size` | Counter | `By` | Count of bytes of intermediate language that have been compiled since the process started. | +| `dotnet.jit.compiled_il.size` | | `By` | Count of bytes of intermediate language that have been compiled since the process started. | This metric reports the same values as calling . @@ -136,13 +136,13 @@ When you build a .NET app, managed code is initially compiled from a high-level Since JIT compilation occurs the first time a method runs, most JIT compilation tends to occur during application startup. Reducing the amount of IL that is JIT compiled can improve application startup time. -Available starting in: .NET 9.0. +Available starting in: .NET 9. ##### Metric: `dotnet.jit.compiled_methods` | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `dotnet.jit.compiled_methods` | Counter | `{method}` | The number of times the JIT compiler (re)compiled methods since the process started. | +| `dotnet.jit.compiled_methods` | | `{method}` | The number of times the JIT compiler (re)compiled methods since the process started. | This metric reports the same values as calling . @@ -150,13 +150,13 @@ When you build a .NET app, managed code is initially compiled from a high-level Since JIT compilation occurs the first time a method runs, most JIT compilation tends to occur during application startup. Reducing the number of methods that need to be JIT compiled can improve application startup time. -Available starting in: .NET 9.0. +Available starting in: .NET 9. ##### Metric: `dotnet.jit.compilation.time` | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `dotnet.jit.compilation.time` | Counter | `s` | The amount of time the JIT compiler has spent compiling methods since the process started. | +| `dotnet.jit.compilation.time` | | `s` | The amount of time the JIT compiler has spent compiling methods since the process started. | This metric reports the same values as calling . @@ -164,86 +164,86 @@ When you build a .NET app, managed code is initially compiled from a high-level Since JIT compilation occurs the first time a method runs, most JIT compilation tends to occur during application startup. Reducing the time spent JIT compiling can improve application startup time. -Available starting in: .NET 9.0. +Available starting in: .NET 9. ##### Metric: `dotnet.thread_pool.thread.count` | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `dotnet.thread_pool.thread.count` | UpDownCounter | `{thread}` | The number of thread pool threads that currently exist. | +| `dotnet.thread_pool.thread.count` | | `{thread}` | The number of thread pool threads that currently exist. | This metric reports the same values as calling . .NET uses a [thread pool](../../standard/threading/the-managed-thread-pool.md) to schedule work items onto other threads. This metric provides the number of worker threads currently managed by that thread pool. -Available starting in: .NET 9.0. +Available starting in: .NET 9. ##### Metric: `dotnet.thread_pool.work_item.count` | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `dotnet.thread_pool.work_item.count` | Counter | `{work_item}` | The number of work items that the thread pool has completed since the process started. | +| `dotnet.thread_pool.work_item.count` | | `{work_item}` | The number of work items that the thread pool has completed since the process started. | This metric reports the same values as calling . .NET uses a [thread pool](../../standard/threading/the-managed-thread-pool.md) to schedule work items onto other threads. This metric provides the number of work items that have been executed by the thread pool threads. -Available starting in: .NET 9.0. +Available starting in: .NET 9. ##### Metric: `dotnet.thread_pool.queue.length` | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `dotnet.thread_pool.queue.length` | UpDownCounter | `{work_item}` | The number of work items that are currently queued to be processed by the thread pool. | +| `dotnet.thread_pool.queue.length` | | `{work_item}` | The number of work items that are currently queued to be processed by the thread pool. | This metric reports the same values as calling . .NET uses a [thread pool](../../standard/threading/the-managed-thread-pool.md) to schedule work items onto other threads. This metric provides the number of work items that are currently queued to be executed by one of the thread pool threads. -Available starting in: .NET 9.0. +Available starting in: .NET 9. ##### Metric: `dotnet.monitor.lock_contentions` | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `dotnet.monitor.lock_contentions` | Counter | `{contention}` | The number of times there was contention when trying to acquire a monitor lock since the process started. | +| `dotnet.monitor.lock_contentions` | | `{contention}` | The number of times there was contention when trying to acquire a monitor lock since the process started. | This metric reports the same values as calling . .NET supports using any managed object as a lock, either with APIs such as or with the [lock statement](../../csharp/language-reference/statements/lock.md). If one thread already holds a lock while a second thread tries to acquire it, this is called _lock contention_. -Available starting in: .NET 9.0. +Available starting in: .NET 9. ##### Metric: `dotnet.timer.count` | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `dotnet.timer.count` | UpDownCounter | `{timer}` | The number of timer instances that are currently active. | +| `dotnet.timer.count` | | `{timer}` | The number of timer instances that are currently active. | This metric reports the same values as calling . -Available starting in: .NET 9.0. +Available starting in: .NET 9. ##### Metric: `dotnet.assembly.count` | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `dotnet.assembly.count` | UpDownCounter | `{assembly}` | The number of .NET assemblies that are currently loaded. | +| `dotnet.assembly.count` | | `{assembly}` | The number of .NET assemblies that are currently loaded. | This metric reports the same values as calling and then checking the length of the returned array. -Available starting in: .NET 9.0. +Available starting in: .NET 9. ##### Metric: `dotnet.exceptions` | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `dotnet.exceptions` | Counter | `{exception}` | The number of exceptions that have been thrown in managed code. | +| `dotnet.exceptions` | | `{exception}` | The number of exceptions that have been thrown in managed code. | | Attribute | Type | Description | Examples | Presence | |---|---|---|---|---|---| -| `error.type` | string | The exception type that was thrown. | `System.OperationCanceledException`; `Contoso.MyException` | `Required` | +| `error.type` | `string` | The exception type that was thrown. | `System.OperationCanceledException`; `Contoso.MyException` | `Required` | This metric reports the same values as counting calls to the event. -Available starting in: .NET 9.0. +Available starting in: .NET 9. diff --git a/docs/core/diagnostics/built-in-metrics-system-net.md b/docs/core/diagnostics/built-in-metrics-system-net.md index 275386b3ab45b..75b8b387bb994 100644 --- a/docs/core/diagnostics/built-in-metrics-system-net.md +++ b/docs/core/diagnostics/built-in-metrics-system-net.md @@ -25,28 +25,28 @@ The `System.Net.NameResolution` metrics report DNS name resolution from or indirectly within higher level APIs on types such as . Most errors when doing a DNS lookup throw a . To better disambiguate the common error cases, socket exceptions with specific are given explicit error names in `error.type`: -| SocketErrorCode | `error.type` | -| --------------- | ------------ | -| | host_not_found | -| | try_again | -| | address_family_not_supported | -| | no_recovery | +| SocketErrorCode | `error.type` | +|-----------------------------------------------------------------|--------------------------------| +| | `host_not_found` | +| | `try_again` | +| | `address_family_not_supported` | +| | `no_recovery` | Socket exceptions with any other `SocketError` value are reported as `System.Net.Sockets.SocketException`. When using OpenTelemetry, the default buckets for this metric are set to [ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]. -Available starting in: .NET 8 +Available starting in: .NET 8. ## `System.Net.Http` @@ -62,20 +62,20 @@ The `System.Net.Http` metrics report HTTP request and connection information fro | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| [`http.client.open_connections`](https://opentelemetry.io/docs/specs/semconv/dotnet/dotnet-http-metrics/#metric-httpclientopen_connections) | UpDownCounter | `{connection}` | Number of outbound HTTP connections that are currently active or idle on the client | +| [`http.client.open_connections`](https://opentelemetry.io/docs/specs/semconv/dotnet/dotnet-http-metrics/#metric-httpclientopen_connections) | | `{connection}` | Number of outbound HTTP connections that are currently active or idle on the client | -| Attribute | Type | Description | Examples | Presence | -|---|---|---|---|---| -| `http.connection.state` | string | State of HTTP connection in the HTTP connection pool. | `active`; `idle` | Always | -| `network.protocol.version` | string | Version of the HTTP protocol used. | `1.1`; `2` | Always | -| `server.address` | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `example.com` | Always | -| `server.port` | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `80`; `8080`; `443` | If not default (`80` for `http` scheme, `443` for `https`) | -| `network.peer.address` | string | Peer IP address of the socket connection. | `10.5.3.2` | Always | -| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Always | +| Attribute | Type | Description | Examples | Presence | +|----------------------------|----------|-------------------------------------------------------|------------------|----------| +| `http.connection.state` | `string` | State of HTTP connection in the HTTP connection pool. | `active`; `idle` | Always | +| `network.protocol.version` | `string` | Version of the HTTP protocol used. | `1.1`; `2` | Always | +| `server.address` | `string` | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `example.com` | Always | +| `server.port` | `int` | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `80`; `8080`; `443` | If not default (`80` for `http` scheme, `443` for `https`) | +| `network.peer.address` | `string` | Peer IP address of the socket connection. | `10.5.3.2` | Always | +| `url.scheme` | `string` | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Always | , when configured to use the default , maintains a cached pool of network connections for sending HTTP messages. This metric counts how many connections are currently in the pool. Active connections are handling active requests. Active connects could be transmitting data or awaiting the client or server. Idle connections aren't handling any requests, but are left open so that future requests can be handled more quickly. -Available starting in: .NET 8 +Available starting in: .NET 8. ##### Metric: `http.client.connection.duration` @@ -83,35 +83,35 @@ Available starting in: .NET 8 | -------- | --------------- | ----------- | -------------- | | [`http.client.connection.duration`](https://opentelemetry.io/docs/specs/semconv/dotnet/dotnet-http-metrics/#metric-httpclientconnectionduration) | Histogram | `s` | The duration of successfully established outbound HTTP connections. | -| Attribute | Type | Description | Examples | Presence | -|---|---|---|---|---| -| `network.protocol.version` | string | Version of the HTTP protocol used. | `1.1`; `2` | Always | -| `server.address` | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `example.com` | Always | -| `server.port` | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `80`; `8080`; `443` | If not default (`80` for `http` scheme, `443` for `https`) | -| `network.peer.address` | string | IP address of the socket connection. | `10.5.3.2` | Always | -| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Always | +| Attribute | Type | Description | Examples | Presence | +|----------------------------|----------|------------------------------------|------------|----------| +| `network.protocol.version` | `string` | Version of the HTTP protocol used. | `1.1`; `2` | Always | +| `server.address` | `string` | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `example.com` | Always | +| `server.port` | `int` | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `80`; `8080`; `443` | If not default (`80` for `http` scheme, `443` for `https`) | +| `network.peer.address` | `string` | IP address of the socket connection. | `10.5.3.2` | Always | +| `url.scheme` | `string` | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Always | This metric is only captured when is configured to use the default . As this metric is tracking the connection duration, and ideally http connections are used for multiple requests, the buckets should be longer than those used for request durations. For example, using [ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ] provides an upper bucket of 5 mins. -Available starting in: .NET 8 +Available starting in: .NET 8. ##### Metric: `http.client.request.duration` | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| [`http.client.request.duration`](https://opentelemetry.io/docs/specs/semconv/dotnet/dotnet-http-metrics/#metric-httpserverrequestduration) | Histogram | `s` | The duration of outbound HTTP requests. | - -| Attribute | Type | Description | Examples | Presence | -|---|---|---|---|---| -| `error.type` | string | Request failure reason: one of the [HTTP request errors](xref:System.Net.Http.HttpRequestError) in snake_case, or a full exception type, or an HTTP 4xx/5xx status code. | `System.Threading.Tasks.TaskCanceledException`; `name_resolution_error`; `secure_connection_error` ; `404` | If request has failed. | -| `http.request.method` | string | HTTP request method. | `GET`; `POST`; `HEAD`; `_OTHER` [2] | Always | -| `http.response.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | If response was received. | -| `network.protocol.version` | string | Version of the HTTP protocol used. | `1.1`; `2` | If response was received. | -| `server.address` | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `example.com` | Always | -| `server.port` | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `80`; `8080`; `443` | Depends on .NET version. [3] | -| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Always | +| [`http.client.request.duration`](https://opentelemetry.io/docs/specs/semconv/dotnet/dotnet-http-metrics/#metric-httpserverrequestduration) | | `s` | The duration of outbound HTTP requests. | + +| Attribute | Type | Description | Examples | Presence | +|-----------------------|----------|----------------------|-------------------------------------|----------| +| `error.type` | `string` | Request failure reason: one of the [HTTP request errors](xref:System.Net.Http.HttpRequestError) in snake_case, or a full exception type, or an HTTP 4xx/5xx status code. | `System.Threading.Tasks.TaskCanceledException`; `name_resolution_error`; `secure_connection_error` ; `404` | If request has failed. | +| `http.request.method` | `string` | HTTP request method. | `GET`; `POST`; `HEAD`; `_OTHER` [2] | Always | +| `http.response.status_code` | `int` | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | If response was received. | +| `network.protocol.version` | `string` | Version of the HTTP protocol used. | `1.1`; `2` | If response was received. | +| `server.address` | `string` | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `example.com` | Always | +| `server.port` | `int` | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `80`; `8080`; `443` | Depends on .NET version. [3] | +| `url.scheme` | `string` | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Always | **[1] `error.type`:** If the request has failed, the value is set to one of the following: @@ -130,7 +130,7 @@ HTTP client request duration measures the time the underlying client handler tak When using OpenTelemetry, the default buckets for this metric are set to [ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]. -Available starting in: .NET 8 +Available starting in: .NET 8. > [!TIP] > [Enrichment](../../fundamentals/networking/telemetry/metrics.md#enrichment) is possible for this metric. @@ -139,33 +139,33 @@ Available starting in: .NET 8 | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| [`http.client.request.time_in_queue`](https://opentelemetry.io/docs/specs/semconv/dotnet/dotnet-http-metrics/#metric-httpclientrequesttime_in_queue) | Histogram | `s` | The amount of time requests spent on a queue waiting for an available connection. | +| [`http.client.request.time_in_queue`](https://opentelemetry.io/docs/specs/semconv/dotnet/dotnet-http-metrics/#metric-httpclientrequesttime_in_queue) | | `s` | The amount of time requests spent on a queue waiting for an available connection. | -| Attribute | Type | Description | Examples | Presence | -|---|---|---|---|---| -| `http.request.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Always | -| `network.protocol.version` | string | Version of the HTTP protocol used. | `1.1`; `2` | Always | -| `server.address` | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `example.com` | Always | -| `server.port` | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `80`; `8080`; `443` | If not default (`80` for `http` scheme, `443` for `https`) | -| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Always | +| Attribute | Type | Description | Examples | Presence | +|----------------------------|----------|------------------------------------|-----------------------|----------| +| `http.request.method` | `string` | HTTP request method. | `GET`; `POST`; `HEAD` | Always | +| `network.protocol.version` | `string` | Version of the HTTP protocol used. | `1.1`; `2` | Always | +| `server.address` | `string` | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `example.com` | Always | +| `server.port` | `int` | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `80`; `8080`; `443` | If not default (`80` for `http` scheme, `443` for `https`) | +| `url.scheme` | `string` | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Always | , when configured to use the default , sends HTTP requests using a pool of network connections. If all connections are busy handling other requests, new requests are placed in a queue and wait until a network connection is available for use. This instrument measures the amount of time HTTP requests spend waiting in that queue, prior to anything being sent across the network. -Available starting in: .NET 8 +Available starting in: .NET 8. ##### Metric: `http.client.active_requests` | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| [`http.client.active_requests`](https://opentelemetry.io/docs/specs/semconv/dotnet/dotnet-http-metrics/#metric-httpserveractive_requests) | UpDownCounter | `{request}` | Number of active HTTP requests. | +| [`http.client.active_requests`](https://opentelemetry.io/docs/specs/semconv/dotnet/dotnet-http-metrics/#metric-httpserveractive_requests) | | `{request}` | Number of active HTTP requests. | -| Attribute | Type | Description | Examples | Presence | -|---|---|---|---|---| -| `http.request.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Always | -| `server.address` | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `example.com` | Always | -| `server.port` | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `80`; `8080`; `443` | If not default (`80` for `http` scheme, `443` for `https`) | -| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Always | +| Attribute | Type | Description | Examples | Presence | +|-----------------------|----------|----------------------|-----------------------|----------| +| `http.request.method` | `string` | HTTP request method. | `GET`; `POST`; `HEAD` | Always | +| `server.address` | `string` | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `example.com` | Always | +| `server.port` | `int` | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `80`; `8080`; `443` | If not default (`80` for `http` scheme, `443` for `https`) | +| `url.scheme` | `string` | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Always | This metric counts how many requests are considered active. Requests are active for the same time period that is measured by the [http.client.request.duration](#metric-httpclientrequestduration) instrument. -Available starting in: .NET 8 +Available starting in: .NET 8. diff --git a/docs/core/diagnostics/metrics-collection.md b/docs/core/diagnostics/metrics-collection.md index f041c4a03c223..0c46afb63aaff 100644 --- a/docs/core/diagnostics/metrics-collection.md +++ b/docs/core/diagnostics/metrics-collection.md @@ -214,7 +214,7 @@ hats-sold recorded measurement 912 ... ``` -### Explaining the sample code +### Sample code explanation The code snippets in this section come from the preceding sample. diff --git a/docs/core/extensions/windows-service-with-installer.md b/docs/core/extensions/windows-service-with-installer.md index 5038333c0c4ef..d4816d364a977 100644 --- a/docs/core/extensions/windows-service-with-installer.md +++ b/docs/core/extensions/windows-service-with-installer.md @@ -186,17 +186,15 @@ After the project reference has been added, configure the _Package.wxs_ file. Op - - + - - + + - - - + + - + diff --git a/docs/core/tools/dotnet-reference-remove.md b/docs/core/tools/dotnet-reference-remove.md index 85e1302b4c42e..0f4c76d13bd60 100644 --- a/docs/core/tools/dotnet-reference-remove.md +++ b/docs/core/tools/dotnet-reference-remove.md @@ -12,7 +12,7 @@ ms.date: 04/02/2025 `dotnet reference remove` - Removes project-to-project (P2P) references. > [!NOTE] -> If you're using .NET 9 SDK or earlier, use the "verb first" form (`dotnet reference remove`) instead. The "noun first" form was introduced in .NET 10. For more information, see [More consistent command order](../whats-new/dotnet-10/sdk.md#more-consistent-command-order). +> If you're using .NET 9 SDK or earlier, use the "verb first" form (`dotnet remove reference`) instead. The "noun first" form was introduced in .NET 10. For more information, see [More consistent command order](../whats-new/dotnet-10/sdk.md#more-consistent-command-order). ## Synopsis diff --git a/docs/core/tools/dotnet-workload-sets.md b/docs/core/tools/dotnet-workload-sets.md index a63a94b2dd205..f15286c0462d6 100644 --- a/docs/core/tools/dotnet-workload-sets.md +++ b/docs/core/tools/dotnet-workload-sets.md @@ -1,8 +1,6 @@ --- title: .NET SDK workload sets description: "Learn how to use workload sets to control which versions of workloads get installed, updated, or restored." -author: tdykstra -ms.author: tdykstra ms.service: dotnet ms.topic: how-to ms.date: 08/02/2024 diff --git a/docs/core/tools/sdk-errors/netsdk1032.md b/docs/core/tools/sdk-errors/netsdk1032.md index 0d2e156f54f06..c8a056c65c776 100644 --- a/docs/core/tools/sdk-errors/netsdk1032.md +++ b/docs/core/tools/sdk-errors/netsdk1032.md @@ -1,7 +1,6 @@ --- title: "NETSDK1032: RuntimeIdentifier and PlatformTarget must be compatible." description: How to resolve the NETSDK1032 error 'RuntimeIdentifier and PlatformTarget must be compatible.' -author: tdykstra ms.topic: error-reference ms.date: 01/14/2025 ai-usage: ai-assisted diff --git a/docs/core/tools/sdk-errors/netsdk1144.md b/docs/core/tools/sdk-errors/netsdk1144.md index f9716a85821d5..5ac2d958945b6 100644 --- a/docs/core/tools/sdk-errors/netsdk1144.md +++ b/docs/core/tools/sdk-errors/netsdk1144.md @@ -1,7 +1,6 @@ --- title: "NETSDK1144: Optimizing assemblies for size failed" description: How to resolve the 'optimizing for size failed' message. -author: tdykstra ms.topic: error-reference ms.date: 01/14/2025 ai-usage: ai-assisted diff --git a/docs/core/tutorials/index.md b/docs/core/tutorials/index.md index ef28e44dce54a..b197764e75836 100644 --- a/docs/core/tutorials/index.md +++ b/docs/core/tutorials/index.md @@ -1,7 +1,6 @@ --- title: .NET Tutorials description: Follow tutorials for learning .NET to build apps and libraries on Mac, Linux, and Windows. -author: tdykstra ms.date: 06/22/2022 ms.custom: devdivchpfy22 titleSuffix: "" diff --git a/docs/core/whats-new/dotnet-10/libraries.md b/docs/core/whats-new/dotnet-10/libraries.md index d160657de7993..0c9ac5d159867 100644 --- a/docs/core/whats-new/dotnet-10/libraries.md +++ b/docs/core/whats-new/dotnet-10/libraries.md @@ -2,14 +2,14 @@ title: What's new in .NET libraries for .NET 10 description: Learn about the updates to the .NET libraries for .NET 10. titleSuffix: "" -ms.date: 07/16/2025 +ms.date: 08/12/2025 ms.topic: whats-new ai-usage: ai-assisted --- # What's new in .NET libraries for .NET 10 -This article describes new features in the .NET libraries for .NET 10. It's been updated for Preview 6. +This article describes new features in the .NET libraries for .NET 10. It's been updated for Preview 7. ## Cryptography @@ -113,6 +113,73 @@ private static bool ValidateMLDsaSignature(ReadOnlySpan data, ReadOnlySpan The PQC algorithms are available on systems where the system cryptographic libraries are OpenSSL 3.5 (or newer) or Windows CNG with PQC support. Also, the new classes are all marked as [`[Experimental]`](../../../fundamentals/syslib-diagnostics/experimental-overview.md) under diagnostic `SYSLIB5006` until development is complete. +#### ML-DSA + +The class includes ease-of-use features that simplify common code patterns: + +```diff +private static byte[] SignData(string privateKeyPath, ReadOnlySpan data) +{ + using (MLDsa signingKey = MLDsa.ImportFromPem(File.ReadAllBytes(privateKeyPath))) + { +- byte[] signature = new byte[signingKey.Algorithm.SignatureSizeInBytes]; +- signingKey.SignData(data, signature); ++ return signingKey.SignData(data); +- return signature; + } +} +``` + +Additionally, this release added support for HashML-DSA, which is called "PreHash" to help distinguish it from "pure" ML-DSA. As the underlying specification interacts with the Object Identifier (OID) value, the SignPreHash and VerifyPreHash methods on this `[Experimental]` type take the dotted-decimal OID as a string. This might evolve as more scenarios using HashML-DSA become well-defined. + +```csharp +private static byte[] SignPreHashSha3_256(MLDsa signingKey, ReadOnlySpan data) +{ + const string Sha3_256Oid = "2.16.840.1.101.3.4.2.8"; + return signingKey.SignPreHash(SHA3_256.HashData(data), Sha3_256Oid); +} +``` + +#### Composite ML-DSA + +.NET 10 introduces new types to support [ietf-lamps-pq-composite-sigs](https://datatracker.ietf.org/doc/draft-ietf-lamps-pq-composite-sigs/) (currently at draft 7), including `CompositeMLDsa` and `CompositeMLDsaAlgorithm` types with implementation of the primitive methods for RSA variants. + +```csharp +var algorithm = CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pss; +using var privateKey = CompositeMLDsa.GenerateKey(algorithm); + +byte[] data = [42]; +byte[] signature = privateKey.SignData(data); + +using var publicKey = CompositeMLDsa.ImportCompositeMLDsaPublicKey(algorithm, privateKey.ExportCompositeMLDsaPublicKey()); +Console.WriteLine(publicKey.VerifyData(data, signature)); // True + +signature[0] ^= 1; // Tamper with signature +Console.WriteLine(publicKey.VerifyData(data, signature)); // False +``` + +### AES KeyWrap with Padding (IETF RFC 5649) + +AES-KWP is an algorithm that is occasionally used in constructions like Cryptographic Message Syntax (CMS) EnvelopedData, where content is encrypted once, but the decryption key needs to be distributed to multiple parties, each one in a distinct secret form. + +.NET now supports the AES-KWP algorithm via instance methods on the class: + +```csharp +private static byte[] DecryptContent(ReadOnlySpan kek, ReadOnlySpan encryptedKey, ReadOnlySpan ciphertext) +{ + using (Aes aes = Aes.Create()) + { + aes.SetKey(kek); + + Span dek = stackalloc byte[256 / 8]; + int length = aes.DecryptKeyWrapPadded(encryptedKey, dek); + + aes.SetKey(dek.Slice(0, length)); + return aes.DecryptCbc(ciphertext); + } +} +``` + ## Globalization and date/time - [New method overloads in ISOWeek for DateOnly type](#new-method-overloads-in-isoweek-for-dateonly-type) @@ -183,6 +250,7 @@ This new API is already used in and improves the p - [Allow specifying ReferenceHandler in `JsonSourceGenerationOptions`](#allow-specifying-referencehandler-in-jsonsourcegenerationoptions) - [Option to disallow duplicate JSON properties](#option-to-disallow-duplicate-json-properties) - [Strict JSON serialization options](#strict-json-serialization-options) +- [PipeReader support for JSON serializer](#pipereader-support-for-json-serializer) ### Allow specifying ReferenceHandler in `JsonSourceGenerationOptions` @@ -224,6 +292,37 @@ These options are read-compatible with now supports , complementing the existing support. Previously, deserializing from a `PipeReader` required converting it to a , but the new overloads eliminate that step by integrating `PipeReader` directly into the serializer. As a bonus, not having to convert from what you're already holding can yield some efficiency benefits. + +This shows the basic usage: + +:::code language="csharp" source="snippets/csharp/PipeReaderBasic.cs"::: + +Here is an example of a producer that produces tokens in chunks and a consumer that receives and displays them: + +:::code language="csharp" source="snippets/csharp/PipeReaderChunks.cs"::: + +All of this is serialized as JSON in the (formatted here for readability): + +```json +[ + { + "Message": "The quick brown fox", + "Timestamp": "2025-08-01T18:37:27.2930151-07:00" + }, + { + "Message": " jumps over", + "Timestamp": "2025-08-01T18:37:27.8594502-07:00" + }, + { + "Message": " the lazy dog.", + "Timestamp": "2025-08-01T18:37:28.3753669-07:00" + } +] +``` + ## System.Numerics - [More left-handed matrix transformation methods](#more-left-handed-matrix-transformation-methods) @@ -328,3 +427,85 @@ A community contribution improved the performance of to launch a process in a separate process group. This allows you to send isolated signals to child processes that could otherwise take down the parent without proper handling. Sending signals is convenient to avoid forceful termination. + +:::code language="csharp" source="snippets/csharp/ProcessGroup.cs"::: + +## WebSocket enhancements + +### WebSocketStream + +.NET 10 introduces `WebSocketStream` , a new API designed to simplify some of the most common—and previously cumbersome— scenarios in .NET. + +Traditional `WebSocket` APIs are low-level and require significant boilerplate: handling buffering and framing, reconstructing messages, managing encoding/decoding, and writing custom wrappers to integrate with streams, channels, or other transport abstractions. These complexities make it difficult to use WebSockets as a transport, especially for apps with streaming or text-based protocols, or event-driven handlers. + +`WebSocketStream` addresses these pain points by providing a -based abstraction over a WebSocket. This enables seamless integration with existing APIs for reading, writing, and parsing data, whether binary or text, and reduces the need for manual plumbing. + +`WebSocketStream` enables high-level, familiar APIs for common WebSocket consumption and production patterns. These APIs reduce friction and make advanced scenarios easier to implement. + +#### Common usage patterns + +Here are a few examples of how `WebSocketStream` simplifies typical `WebSocket` workflows: + +##### Streaming text protocol (for example, STOMP) + +:::code language="csharp" source="snippets/csharp/WebSocketStreamText.cs"::: + +##### Streaming binary protocol (for example, AMQP) + +:::code language="csharp" source="snippets/csharp/WebSocketStreamBinary.cs"::: + +##### Read a single message as a stream (for example, JSON deserialization) + +:::code language="csharp" source="snippets/csharp/WebSocketStreamRead.cs"::: + +##### Write a single message as a stream (for example, binary serialization) + +:::code language="csharp" source="snippets/csharp/WebSocketStreamWrite.cs"::: + +## TLS enhancements + +### TLS 1.3 for macOS (client) + +.NET 10 adds client-side TLS 1.3 support on macOS by integrating Apple's Network.framework into and . Historically, macOS used Secure Transport which doesn't support TLS 1.3; opting into Network.framework enables TLS 1.3. + +#### Scope and behavior + +- macOS only, client-side in this release. +- Opt-in. Existing apps continue to use the current stack unless enabled. +- When enabled, older TLS versions (TLS 1.0 and 1.1) might no longer be available via Network.framework. + +#### How to enable + +Use an AppContext switch in code: + +```csharp +// Opt in to Network.framework-backed TLS on Apple platforms +AppContext.SetSwitch("System.Net.Security.UseNetworkFramework", true); + +using var client = new HttpClient(); +var html = await client.GetStringAsync("https://example.com"); +``` + +Or use an environment variable: + +```bash +# Opt-in via environment variable (set for the process or machine as appropriate) +DOTNET_SYSTEM_NET_SECURITY_USENETWORKFRAMEWORK=1 +# or +DOTNET_SYSTEM_NET_SECURITY_USENETWORKFRAMEWORK=true +``` + +#### Notes + +- TLS 1.3 applies to and APIs built on it (for example, /). +- Cipher suites are controlled by macOS via Network.framework. +- Underlying stream behavior might differ when Network.framework is enabled (for example, buffering, read/write completion, cancellation semantics). +- Semantics might differ for zero-byte reads. Avoid relying on zero-length reads for detecting data availability. +- Certain internationalized domain names (IDN) hostnames might be rejected by Network.framework. Prefer ASCII/Punycode (A-label) hostnames or validate names against macOS/Network.framework constraints. +- If your app relies on specific edge-case behavior, validate it under Network.framework. diff --git a/docs/core/whats-new/dotnet-10/overview.md b/docs/core/whats-new/dotnet-10/overview.md index 2b70efb375c74..02d2f1a8b4592 100644 --- a/docs/core/whats-new/dotnet-10/overview.md +++ b/docs/core/whats-new/dotnet-10/overview.md @@ -2,14 +2,14 @@ title: What's new in .NET 10 description: Learn about the new features introduced in .NET 10 for the runtime, libraries, and SDK. Also find links to what's new in other areas, such as ASP.NET Core. titleSuffix: "" -ms.date: 07/16/2025 +ms.date: 08/12/2025 ms.topic: whats-new ai-usage: ai-assisted --- # What's new in .NET 10 -Learn about the new features in .NET 10 and find links to further documentation. This page has been updated for Preview 6. +Learn about the new features in .NET 10 and find links to further documentation. This page has been updated for Preview 7. .NET 10, the successor to [.NET 9](../dotnet-9/overview.md), is [supported for three years](https://dotnet.microsoft.com/platform/support/policy/dotnet-core) as a long-term support (LTS) release. You can [download .NET 10 here](https://get.dot.net/10). @@ -23,14 +23,14 @@ For more information, see [What's new in the .NET 10 runtime](runtime.md). ## .NET libraries -The .NET 10 libraries introduce new APIs in cryptography, globalization, numerics, serialization, collections, and diagnostics, and when working with ZIP files. New JSON serialization options include disallowing duplicate properties and strict serialization settings. Post-quantum cryptography support has been expanded with Windows Cryptography API: Next Generation (CNG) support. +The .NET 10 libraries introduce new APIs in cryptography, globalization, numerics, serialization, collections, and diagnostics, and when working with ZIP files. New JSON serialization options include disallowing duplicate properties, strict serialization settings, and `PipeReader` support for improved efficiency. Post-quantum cryptography support has been expanded with Windows Cryptography API: Next Generation (CNG) support, enhanced ML-DSA with simplified APIs and HashML-DSA support, plus Composite ML-DSA. Additional cryptography enhancements include AES KeyWrap with Padding support. New networking capabilities include `WebSocketStream` for simplified `WebSocket` usage and TLS 1.3 support for macOS clients. Process management gains Windows process group support for better signal isolation. For more information, see [What's new in the .NET 10 libraries](libraries.md). For details on JSON serialization, see [System.Text.Json overview](/dotnet/standard/serialization/system-text-json/overview). ## .NET SDK -The .NET 10 SDK includes support for [Microsoft.Testing.Platform](../../testing/microsoft-testing-platform-intro.md) in `dotnet test`, standardizes CLI command order, and updates the CLI to generate native tab-completion scripts for popular shells. For containers, console apps can natively create container images, and a new property lets you explicitly set the format of container images. The SDK also supports platform-specific .NET tools, one-shot tool execution with `dotnet tool exec`, the new `dnx` tool execution script, CLI introspection with `--cli-schema`, and enhanced file-based apps with publish support and native AOT. +The .NET 10 SDK includes support for [Microsoft.Testing.Platform](../../testing/microsoft-testing-platform-intro.md) in `dotnet test`, standardizes CLI command order, and updates the CLI to generate native tab-completion scripts for popular shells. For containers, console apps can natively create container images, and a new property lets you explicitly set the format of container images. The SDK also supports platform-specific .NET tools with enhanced compatibility via the `any` RuntimeIdentifier, one-shot tool execution with `dotnet tool exec`, the new `dnx` tool execution script, CLI introspection with `--cli-schema`, and enhanced file-based apps with publish support and native AOT. For more information, see [What's new in the SDK for .NET 10](sdk.md). For details on .NET tools, see [Manage .NET tools](/dotnet/core/tools/global-tools). diff --git a/docs/core/whats-new/dotnet-10/runtime.md b/docs/core/whats-new/dotnet-10/runtime.md index 36e804b2ae8f9..174f9937fd37e 100644 --- a/docs/core/whats-new/dotnet-10/runtime.md +++ b/docs/core/whats-new/dotnet-10/runtime.md @@ -2,13 +2,13 @@ title: What's new in .NET 10 runtime description: Learn about the new features introduced in the .NET 10 runtime. titleSuffix: "" -ms.date: 07/16/2025 +ms.date: 08/12/2025 ms.topic: whats-new ai-usage: ai-assisted --- # What's new in the .NET 10 runtime -This article describes new features and performance improvements in the .NET runtime for .NET 10. It has been updated for Preview 6. +This article describes new features and performance improvements in the .NET runtime for .NET 10. It's been updated for Preview 7. ## JIT compiler improvements @@ -48,7 +48,7 @@ private static void Main() } ``` -On x64, we pass the members of `Point` to `Consume` in separate registers, and since physical promotion kicked in for the local `p`, we don't allocate anything on the stack first: +On x64, the members of `Point` are passed to `Consume` in separate registers, and since physical promotion kicked in for the local `p`, nothing is allocated on the stack first: ```asm Program:Main() (FullOpts): @@ -57,7 +57,7 @@ Program:Main() (FullOpts): tail.jmp [Program:Consume(Program+Point)] ``` -Now, suppose we changed the type of the members of `Point` to `int` instead of `long`. Because an `int` is four bytes wide, and registers are eight bytes wide on x64, the calling convention requires us to pass the members of `Point` in one register. Previously, the JIT compiler would first store the values to memory, and then load the eight-byte chunk into a register. With the .NET 10 improvements, the JIT compiler can now place the promoted members of struct arguments into shared registers directly: +Now, suppose the type of the members of `Point` was changed to `int` instead of `long`. Because an `int` is four bytes wide, and registers are eight bytes wide on x64, the calling convention requires the members of `Point` to be passed in one register. Previously, the JIT compiler would first store the values to memory, and then load the eight-byte chunk into a register. With the .NET 10 improvements, the JIT compiler can now place the promoted members of struct arguments into shared registers directly: ```asm Program:Main() (FullOpts): diff --git a/docs/core/whats-new/dotnet-10/sdk.md b/docs/core/whats-new/dotnet-10/sdk.md index 4e9670b714c64..6eb8d37e46818 100644 --- a/docs/core/whats-new/dotnet-10/sdk.md +++ b/docs/core/whats-new/dotnet-10/sdk.md @@ -2,14 +2,14 @@ title: What's new in the SDK and tooling for .NET 10 description: Learn about the new .NET SDK features introduced in .NET 10. titleSuffix: "" -ms.date: 07/16/2025 +ms.date: 08/12/2025 ms.topic: whats-new ai-usage: ai-assisted --- # What's new in the SDK and tooling for .NET 10 -This article describes new features and enhancements in the .NET SDK for .NET 10. It has been updated for Preview 6. +This article describes new features and enhancements in the .NET SDK for .NET 10. It's been updated for Preview 7. ## .NET tools enhancements @@ -59,6 +59,27 @@ The actual implementation of the `dnx` command is in the `dotnet` CLI itself, al For more information about managing .NET tools, see [Manage .NET tools](../../tools/global-tools.md). +### Use the `any` RuntimeIdentifier with platform-specific .NET tools + +The [platform-specific .NET tools](#platform-specific-net-tools) feature is great for making sure tools are optimized for specific platforms that you target ahead-of-time. However, there are times where you won't know all of the platforms that you'd like to target, or sometimes .NET itself will learn how to support a new platform, and you'd like your tool to be runnable there too. + +To make your tool work this way, add the `any` runtime identifier to your project file: + +```xml + + + linux-x64; + linux-arm64; + macos-arm64; + win-x64; + win-arm64; + any + + +``` + +This RuntimeIdentifier is at the 'root' of the platform-compatibility checking, and since it declares support for _any_ platform, the tool that gets packaged will be the most compatible kind of tool - a framework-dependent, platform-agnostic .NET DLL, which requires a compatible .NET Runtime to execute. When you perform a `dotnet pack` to create your tool, you'll see a new package for the `any` RuntimeIdentifier appear alongside the other platform-specific packages and the top-level manifest package. + ### CLI introspection with `--cli-schema` A new `--cli-schema` option is available on all CLI commands. When used, it outputs a JSON representation of the CLI command tree for the invoked command or subcommand. This is useful for tool authors, shell integration, and advanced scripting. diff --git a/docs/core/whats-new/dotnet-10/snippets/csharp/PipeReaderBasic.cs b/docs/core/whats-new/dotnet-10/snippets/csharp/PipeReaderBasic.cs new file mode 100644 index 0000000000000..2087bc145425d --- /dev/null +++ b/docs/core/whats-new/dotnet-10/snippets/csharp/PipeReaderBasic.cs @@ -0,0 +1,19 @@ +using System; +using System.IO.Pipelines; +using System.Text.Json; +using System.Threading.Tasks; + +var pipe = new Pipe(); + +// Serialize to writer +await JsonSerializer.SerializeAsync(pipe.Writer, new Person("Alice")); +await pipe.Writer.CompleteAsync(); + +// Deserialize from reader +var result = await JsonSerializer.DeserializeAsync(pipe.Reader); +await pipe.Reader.CompleteAsync(); + +Console.WriteLine($"Your name is {result.Name}."); +// Output: Your name is Alice. + +record Person(string Name); \ No newline at end of file diff --git a/docs/core/whats-new/dotnet-10/snippets/csharp/PipeReaderChunks.cs b/docs/core/whats-new/dotnet-10/snippets/csharp/PipeReaderChunks.cs new file mode 100644 index 0000000000000..8c043ddcb591b --- /dev/null +++ b/docs/core/whats-new/dotnet-10/snippets/csharp/PipeReaderChunks.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.IO.Pipelines; +using System.Text.Json; +using System.Threading.Tasks; + +var pipe = new Pipe(); + +// Producer writes to the pipe in chunks. +var producerTask = Task.Run(async () => +{ + async static IAsyncEnumerable GenerateResponse() + { + yield return new Chunk("The quick brown fox", DateTime.Now); + await Task.Delay(500); + yield return new Chunk(" jumps over", DateTime.Now); + await Task.Delay(500); + yield return new Chunk(" the lazy dog.", DateTime.Now); + } + + await JsonSerializer.SerializeAsync>(pipe.Writer, GenerateResponse()); + await pipe.Writer.CompleteAsync(); +}); + +// Consumer reads from the pipe and outputs to console. +var consumerTask = Task.Run(async () => +{ + var thinkingString = "..."; + var clearThinkingString = new string("\b\b\b"); + var lastTimestamp = DateTime.MinValue; + + // Read response to end. + Console.Write(thinkingString); + await foreach (var chunk in JsonSerializer.DeserializeAsyncEnumerable(pipe.Reader)) + { + Console.Write(clearThinkingString); + Console.Write(chunk.Message); + Console.Write(thinkingString); + lastTimestamp = DateTime.Now; + } + + Console.Write(clearThinkingString); + Console.WriteLine($" Last message sent at {lastTimestamp}."); + + await pipe.Reader.CompleteAsync(); +}); + +await producerTask; +await consumerTask; + +record Chunk(string Message, DateTime Timestamp); \ No newline at end of file diff --git a/docs/core/whats-new/dotnet-10/snippets/csharp/ProcessGroup.cs b/docs/core/whats-new/dotnet-10/snippets/csharp/ProcessGroup.cs new file mode 100644 index 0000000000000..fce205adc4386 --- /dev/null +++ b/docs/core/whats-new/dotnet-10/snippets/csharp/ProcessGroup.cs @@ -0,0 +1,73 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; + +class Program +{ + static void Main(string[] args) + { + bool isChildProcess = args.Length > 0 && args[0] == "child"; + if (!isChildProcess) + { + var psi = new ProcessStartInfo + { + FileName = Environment.ProcessPath, + Arguments = "child", + CreateNewProcessGroup = true, + }; + + using Process process = Process.Start(psi)!; + Thread.Sleep(5_000); + + GenerateConsoleCtrlEvent(CTRL_C_EVENT, (uint)process.Id); + process.WaitForExit(); + + Console.WriteLine("Child process terminated gracefully, continue with the parent process logic if needed."); + } + else + { + // If you need to send a CTRL+C, the child process needs to re-enable CTRL+C handling, if you own the code, you can call SetConsoleCtrlHandler(NULL, FALSE). + // see https://learn.microsoft.com/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw#remarks + SetConsoleCtrlHandler((IntPtr)null, false); + + Console.WriteLine("Greetings from the child process! I need to be gracefully terminated, send me a signal!"); + + bool stop = false; + + var registration = PosixSignalRegistration.Create(PosixSignal.SIGINT, ctx => + { + stop = true; + ctx.Cancel = true; + Console.WriteLine("Received CTRL+C, stopping..."); + }); + + StreamWriter sw = File.AppendText("log.txt"); + int i = 0; + while (!stop) + { + Thread.Sleep(1000); + sw.WriteLine($"{++i}"); + Console.WriteLine($"Logging {i}..."); + } + + // Clean up + sw.Dispose(); + registration.Dispose(); + + Console.WriteLine("Thanks for not killing me!"); + } + } + + private const int CTRL_C_EVENT = 0; + private const int CTRL_BREAK_EVENT = 1; + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool SetConsoleCtrlHandler(IntPtr handler, [MarshalAs(UnmanagedType.Bool)] bool Add); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool GenerateConsoleCtrlEvent(uint dwCtrlEvent, uint dwProcessGroupId); +} \ No newline at end of file diff --git a/docs/core/whats-new/dotnet-10/snippets/csharp/WebSocketStreamBinary.cs b/docs/core/whats-new/dotnet-10/snippets/csharp/WebSocketStreamBinary.cs new file mode 100644 index 0000000000000..286c1b253ac22 --- /dev/null +++ b/docs/core/whats-new/dotnet-10/snippets/csharp/WebSocketStreamBinary.cs @@ -0,0 +1,16 @@ +using System; +using System.IO; +using System.Net.WebSockets; +using System.Threading; +using System.Threading.Tasks; + +// Streaming binary protocol (for example, AMQP). +Stream transportStream = WebSocketStream.Create( + connectedWebSocket, + WebSocketMessageType.Binary, + closeTimeout: TimeSpan.FromSeconds(10)); +await message.SerializeToStreamAsync(transportStream, cancellationToken); +var receivePayload = new byte[payloadLength]; +await transportStream.ReadExactlyAsync(receivePayload, cancellationToken); +transportStream.Dispose(); +// `Dispose` automatically handles closing handshake. \ No newline at end of file diff --git a/docs/core/whats-new/dotnet-10/snippets/csharp/WebSocketStreamRead.cs b/docs/core/whats-new/dotnet-10/snippets/csharp/WebSocketStreamRead.cs new file mode 100644 index 0000000000000..5ecce13b17819 --- /dev/null +++ b/docs/core/whats-new/dotnet-10/snippets/csharp/WebSocketStreamRead.cs @@ -0,0 +1,8 @@ +using System.IO; +using System.Net.WebSockets; +using System.Text.Json; + +// Reading a single message as a stream (for example, JSON deserialization). +using Stream messageStream = WebSocketStream.CreateReadableMessageStream(connectedWebSocket, WebSocketMessageType.Text); +// JsonSerializer.DeserializeAsync reads until the end of stream. +var appMessage = await JsonSerializer.DeserializeAsync(messageStream); \ No newline at end of file diff --git a/docs/core/whats-new/dotnet-10/snippets/csharp/WebSocketStreamText.cs b/docs/core/whats-new/dotnet-10/snippets/csharp/WebSocketStreamText.cs new file mode 100644 index 0000000000000..6295107f6af9b --- /dev/null +++ b/docs/core/whats-new/dotnet-10/snippets/csharp/WebSocketStreamText.cs @@ -0,0 +1,15 @@ +using System.IO; +using System.Net.WebSockets; +using System.Threading; +using System.Threading.Tasks; + +// Streaming text protocol (for example, STOMP). +using Stream transportStream = WebSocketStream.Create( + connectedWebSocket, + WebSocketMessageType.Text, + ownsWebSocket: true); +// Integration with Stream-based APIs. +// Don't close the stream, as it's also used for writing. +using var transportReader = new StreamReader(transportStream, leaveOpen: true); +var line = await transportReader.ReadLineAsync(cancellationToken); // Automatic UTF-8 and new line handling. +transportStream.Dispose(); // Automatic closing handshake handling on `Dispose`. \ No newline at end of file diff --git a/docs/core/whats-new/dotnet-10/snippets/csharp/WebSocketStreamWrite.cs b/docs/core/whats-new/dotnet-10/snippets/csharp/WebSocketStreamWrite.cs new file mode 100644 index 0000000000000..58ad0b9b090f1 --- /dev/null +++ b/docs/core/whats-new/dotnet-10/snippets/csharp/WebSocketStreamWrite.cs @@ -0,0 +1,15 @@ +using System; +using System.IO; +using System.Net.WebSockets; +using System.Threading; +using System.Threading.Tasks; + +// Writing a single message as a stream (for example, binary serialization). +public async Task SendMessageAsync(AppMessage message, CancellationToken cancellationToken) +{ + using Stream messageStream = WebSocketStream.CreateWritableMessageStream(_connectedWebSocket, WebSocketMessageType.Binary); + foreach (ReadOnlyMemory chunk in message.SplitToChunks()) + { + await messageStream.WriteAsync(chunk, cancellationToken); + } +} // EOM sent on messageStream.Dispose(). \ No newline at end of file diff --git a/docs/core/whats-new/dotnet-10/snippets/csharp/snippets.csproj b/docs/core/whats-new/dotnet-10/snippets/csharp/snippets.csproj new file mode 100644 index 0000000000000..6f0d5c788bb02 --- /dev/null +++ b/docs/core/whats-new/dotnet-10/snippets/csharp/snippets.csproj @@ -0,0 +1,26 @@ + + + + net8.0 + Library + enable + enable + preview + false + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/csharp/asynchronous-programming/async-scenarios.md b/docs/csharp/asynchronous-programming/async-scenarios.md index e72592944ddfc..e63c3c0efecb3 100644 --- a/docs/csharp/asynchronous-programming/async-scenarios.md +++ b/docs/csharp/asynchronous-programming/async-scenarios.md @@ -208,6 +208,74 @@ Avoid writing code that depends on the state of global objects or the execution A recommended goal is to achieve complete or near-complete [Referential Transparency](https://en.wikipedia.org/wiki/Referential_transparency) in your code. This approach results in a predictable, testable, and maintainable codebase. +### Synchronous access to asynchronous operations + +In scenarios, you might need to block on asynchronous operations when the `await` keyword isn't available throughout your call stack. This situation occurs in legacy codebases or when integrating asynchronous methods into synchronous APIs that can't be changed. + +> [!WARNING] +> Synchronous blocking on asynchronous operations can lead to deadlocks and should be avoided whenever possible. The preferred solution is to use `async`/`await` throughout your call stack. + +When you must block synchronously on a `Task`, here are the available approaches, listed from most to least preferred: + +- [Use GetAwaiter().GetResult()](#use-getawaitergetresult) +- [Use Task.Run for complex scenarios](#use-taskrun-for-complex-scenarios) +- [Use Wait() and Result](#use-wait-and-result) + +#### Use GetAwaiter().GetResult() + +The `GetAwaiter().GetResult()` pattern is generally the preferred approach when you must block synchronously: + +```csharp +// When you cannot use await +Task task = GetDataAsync(); +string result = task.GetAwaiter().GetResult(); +``` + +This approach: + +- Preserves the original exception without wrapping it in an `AggregateException`. +- Blocks the current thread until the task completes. +- Still carries deadlock risk if not used carefully. + +#### Use Task.Run for complex scenarios + +For complex scenarios where you need to isolate the asynchronous work: + +```csharp +// Offload to thread pool to avoid context deadlocks +string result = Task.Run(async () => await GetDataAsync()).GetAwaiter().GetResult(); +``` + +This pattern: + +- Executes the asynchronous method on a thread pool thread. +- Can help avoid some deadlock scenarios. +- Adds overhead by scheduling work to the thread pool. + +#### Use Wait() and Result + +You can use a blocking approach by calling and . However, this approach is discouraged because it wraps exceptions in . + +```csharp +Task task = GetDataAsync(); +task.Wait(); +string result = task.Result; +``` + +Problems with `Wait()` and `Result`: + +- Exceptions are wrapped in `AggregateException`, making error handling more complex. +- Higher deadlock risk. +- Less clear intent in code. + +#### Additional considerations + +- Deadlock prevention: Be especially careful in UI applications or when using a synchronization context. +- Performance impact: Blocking threads reduces scalability. +- Exception handling: Test error scenarios carefully as exception behavior differs between patterns. + +For more detailed guidance on the challenges and considerations of synchronous wrappers for asynchronous methods, see [Should I expose synchronous wrappers for asynchronous methods?](https://devblogs.microsoft.com/pfxteam/should-i-expose-synchronous-wrappers-for-asynchronous-methods/). + ## Review the complete example The following code represents the complete example, which is available in the *Program.cs* example file. diff --git a/docs/csharp/language-reference/compiler-messages/assembly-references.md b/docs/csharp/language-reference/compiler-messages/assembly-references.md index 3bc1212c8d194..65217f6cfa0e7 100644 --- a/docs/csharp/language-reference/compiler-messages/assembly-references.md +++ b/docs/csharp/language-reference/compiler-messages/assembly-references.md @@ -89,6 +89,35 @@ These compiler errors indicate one of these problems in your code: - You used the [global scope operator, (`::`)](../operators/namespace-alias-qualifier.md) when the type isn't in the global namespace. - You're accessing an extension member and either the namespace isn't specified in a `using` directive, or you're not referencing the assembly that contains the extension. +### When the assembly appears to be referenced + +If the assembly appears to be referenced in your project but you still receive CS0012, try these troubleshooting steps: + +- Restore packages: Run `dotnet restore` to ensure all package references are properly resolved, especially after installing or uninstalling NuGet packages. + +- Clear the NuGet package cache and restore: + + ```console + dotnet nuget locals all --clear + dotnet restore + ``` + +- Check for version conflicts: Verify that all referenced assemblies use compatible versions. Look for binding redirect warnings in the build output. + +- Clean the solution and rebuild to ensure no stale references remain: + + ```console + dotnet clean + dotnet build + ``` + +- Verify package integrity: If the error occurred after package operations, ensure the package was installed correctly by removing and reinstalling it: + + ```console + dotnet remove package [PackageName] + dotnet add package [PackageName] + ``` + ## Type forwarding - **CS1068**: *The type name could not be found in the global namespace. This type has been forwarded to another assembly. Consider adding a reference to that assembly.* diff --git a/docs/csharp/language-reference/compiler-messages/cs0050.md b/docs/csharp/language-reference/compiler-messages/cs0050.md index fd8f0454de233..14f3529b7044a 100644 --- a/docs/csharp/language-reference/compiler-messages/cs0050.md +++ b/docs/csharp/language-reference/compiler-messages/cs0050.md @@ -12,9 +12,9 @@ ms.assetid: dead2d28-f4db-4afe-b8dd-38968625f7c3 Inconsistent accessibility: return type 'type' is less accessible than method 'method' - The return type and each of the types referenced in the formal parameter list of a method must be at least as accessible as the method itself. For more information, see [Access Modifiers](../../programming-guide/classes-and-structs/access-modifiers.md). + The return type and each of the types referenced in the formal parameter list of a method must be at least as accessible as the method itself. This includes type arguments of generic types used in the return type or parameters. For more information, see [Access Modifiers](../../programming-guide/classes-and-structs/access-modifiers.md). -## Example +## Examples The following sample generates CS0050 because no accessibility modifier is supplied for `MyClass`, and its accessibility therefore defaults to `private`: @@ -36,3 +36,43 @@ public class MyClass2 public static void Main() { } } ``` + +CS0050 can also occur when a generic type's type argument is less accessible than the method: + +```csharp +// CS0050_Generic.cs +using System.Collections.ObjectModel; + +internal class CeisData // Internal class +{ + public string Name { get; set; } +} + +public class MyClass +{ + public static ObservableCollection BuildCeis() // CS0050 + { + return new ObservableCollection(); + } +} +``` + +To fix this error, make the type argument at least as accessible as the method: + +```csharp +// Fixed version +using System.Collections.ObjectModel; + +public class CeisData // Now public +{ + public string Name { get; set; } +} + +public class MyClass +{ + public static ObservableCollection BuildCeis() // OK + { + return new ObservableCollection(); + } +} +``` diff --git a/docs/csharp/language-reference/tokens/raw-string.md b/docs/csharp/language-reference/tokens/raw-string.md index 1ccadc761f788..8623789fd6efc 100644 --- a/docs/csharp/language-reference/tokens/raw-string.md +++ b/docs/csharp/language-reference/tokens/raw-string.md @@ -17,9 +17,9 @@ Raw string literals can span multiple lines: The following rules govern the interpretation of a multi-line raw string literal: -- The opening quotes must be the last non-comment token on its respective line, and the closing quote must be the first non-comment token on its respective line. +- The opening quotes must be the last non-whitespace characters on their line, and the closing quotes must be the first non-whitespace characters on their line. - Any whitespace to the left of the closing quotes is removed from all lines of the raw string literal. -- Whitespace following the opening quote on the same line is ignored. +- Any whitespace following the opening quotes on the same line is ignored. - Whitespace only lines following the opening quote are included in the string literal. - If a whitespace precedes the end delimiter on the same line, the exact number and kind of whitespace characters (for example, spaces vs. tabs) must exist at the beginning of each content line. Specifically, a space does not match a horizontal tab, and vice versa. - The newline before the closing quotes isn't included in the literal string. diff --git a/docs/csharp/programming-guide/indexers/index.md b/docs/csharp/programming-guide/indexers/index.md index c663e77b2c0ee..bfa1d8af9a343 100644 --- a/docs/csharp/programming-guide/indexers/index.md +++ b/docs/csharp/programming-guide/indexers/index.md @@ -55,6 +55,14 @@ Another common scenario is when you need to model a dictionary or a map. This sc In this example, the `ArgsAction` collection maps closely to the underlying collection. The `get` determines if a given option is configured. If so, it returns the associated with that option. If not, it returns an that does nothing. The public accessor doesn't include a `set` accessor. Rather, the design is using a public method for setting options. +### Date-based indexers + +When working with date-based data, you can use either or as indexer keys. Use when you only need the date part and want to avoid time-related complications. The following example shows a temperature tracking system that uses `DateOnly` as the primary indexer key: + +:::code language="csharp" source="./snippets/indexers/DateOnlyIndexer.cs"::: + +This example demonstrates both `DateOnly` and `DateTime` indexers. While the `DateOnly` indexer is the primary interface, the `DateTime` overload provides convenience by extracting only the date portion. This approach ensures that all temperature data for a given day is treated consistently, regardless of the time component. + ### Multi-Dimensional Maps You can create indexers that use multiple arguments. In addition, those arguments aren't constrained to be the same type. diff --git a/docs/csharp/programming-guide/indexers/snippets/indexers/DateOnlyIndexer.cs b/docs/csharp/programming-guide/indexers/snippets/indexers/DateOnlyIndexer.cs new file mode 100644 index 0000000000000..9e9bca8ec27c4 --- /dev/null +++ b/docs/csharp/programming-guide/indexers/snippets/indexers/DateOnlyIndexer.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; + +namespace Indexers; + +public class DailyTemperatureData +{ + private readonly Dictionary _temperatureData = new(); + + // Indexer using DateOnly for date-only scenarios + public (double High, double Low) this[DateOnly date] + { + get + { + if (_temperatureData.TryGetValue(date, out var temp)) + { + return temp; + } + throw new KeyNotFoundException($"No temperature data available for {date:yyyy-MM-dd}"); + } + set + { + _temperatureData[date] = value; + } + } + + // Overload using DateTime for convenience, but only uses the date part + public (double High, double Low) this[DateTime dateTime] + { + get => this[DateOnly.FromDateTime(dateTime)]; + set => this[DateOnly.FromDateTime(dateTime)] = value; + } + + public bool HasDataFor(DateOnly date) => _temperatureData.ContainsKey(date); + + public IEnumerable AvailableDates => _temperatureData.Keys; +} \ No newline at end of file diff --git a/docs/csharp/programming-guide/indexers/snippets/indexers/DateOnlyProgram.cs b/docs/csharp/programming-guide/indexers/snippets/indexers/DateOnlyProgram.cs new file mode 100644 index 0000000000000..619898df3159b --- /dev/null +++ b/docs/csharp/programming-guide/indexers/snippets/indexers/DateOnlyProgram.cs @@ -0,0 +1,32 @@ +using System; +using Indexers; + +namespace DateOnlyExample; + +class Program +{ + static void Main() + { + var temperatureData = new DailyTemperatureData(); + + // Store temperature data using DateOnly + var today = DateOnly.FromDateTime(DateTime.Today); + temperatureData[today] = (75.2, 62.1); + temperatureData[today.AddDays(1)] = (78.5, 64.3); + temperatureData[today.AddDays(-1)] = (72.8, 59.7); + + // Retrieve data using DateOnly + Console.WriteLine($"Today's temperature: High {temperatureData[today].High}°F, Low {temperatureData[today].Low}°F"); + + // Can also use DateTime - only the date part is used + var tomorrow = DateTime.Today.AddDays(1); + Console.WriteLine($"Tomorrow's temperature: High {temperatureData[tomorrow].High}°F, Low {temperatureData[tomorrow].Low}°F"); + + // Show available dates + Console.WriteLine("Available temperature data for:"); + foreach (var date in temperatureData.AvailableDates) + { + Console.WriteLine($" {date:yyyy-MM-dd}"); + } + } +} \ No newline at end of file diff --git a/docs/csharp/programming-guide/indexers/snippets/indexers/Indexers.csproj b/docs/csharp/programming-guide/indexers/snippets/indexers/Indexers.csproj index 16e0a5ccc0d59..93d988e5f1a8c 100644 --- a/docs/csharp/programming-guide/indexers/snippets/indexers/Indexers.csproj +++ b/docs/csharp/programming-guide/indexers/snippets/indexers/Indexers.csproj @@ -5,7 +5,6 @@ net9.0 enable enable - preview diff --git a/docs/framework/release-notes/release-notes.md b/docs/framework/release-notes/release-notes.md index 695612d127816..865d75903c5b2 100644 --- a/docs/framework/release-notes/release-notes.md +++ b/docs/framework/release-notes/release-notes.md @@ -11,7 +11,8 @@ The .NET Framework updates include cumulative security and reliability improveme .NET Framework cumulative update releases are discussed in detail in the following individual release notes: -* April 22, 2025 - [cumulative update preview](./2025/04-22-april-cumulative-update-preview.md) **New Release** +* July 8, 2025 - [cumulative update](./2025/07-08-july-cumulative-update.md) +* April 22, 2025 - [cumulative update preview](./2025/04-22-april-cumulative-update-preview.md) * April 8, 2025 - [cumulative update](./2025/04-08-april-cumulative-update.md) * March 25, 2025 - [cumulative update preview](./2025/03-25-march-cumulative-update-preview.md) * January 28, 2025 - [cumulative update preview](./2025/01-28-january-cumulative-update-preview.md) diff --git a/docs/fundamentals/code-analysis/quality-rules/ca1848.md b/docs/fundamentals/code-analysis/quality-rules/ca1848.md index 8660f6af09574..ced058485687d 100644 --- a/docs/fundamentals/code-analysis/quality-rules/ca1848.md +++ b/docs/fundamentals/code-analysis/quality-rules/ca1848.md @@ -1,7 +1,7 @@ --- title: "CA1848: Use the LoggerMessage delegates (code analysis)" description: "Learn about code analysis rule CA1848: Use the LoggerMessage delegates" -ms.date: 01/19/2022 +ms.date: 08/04/2025 f1_keywords: - "LoggerMessageDefineAnalyzer" - "CA1848" @@ -26,13 +26,51 @@ Use of [logger extension methods](xref:Microsoft.Extensions.Logging.LoggerExtens ## Rule description -For high-performance logging scenarios, use the pattern. +For high-performance logging scenarios, use the [LoggerMessage](../../../core/extensions/logger-message-generator.md) pattern instead of extension methods. ## How to fix violations -Use `LoggerMessage` to fix violations of this rule. +Use to fix violations of this rule. (Or, if you're using .NET 5 or earlier, use the class.) - provides the following performance advantages over Logger extension methods: +```csharp +public class SomethingDoer +{ + private readonly ILogger _logger; + public SomethingDoer(ILogger logger) + { + _logger = logger; + } + + public void DoSomething() + { + // This call violates CA1848. + _logger.LogInformation("Did something!"); + } +} +``` + +The following code fixes the violation. + +```csharp +public partial class SomethingDoer +{ + private readonly ILogger _logger; + public SomethingDoer(ILogger logger) + { + _logger = logger; + } + + public void DoSomething() + { + Log_DidSomething(); + } + + [LoggerMessage(Level = LogLevel.Information, Message = "Did something!")] + private partial void Log_DidSomething(); +} +``` + + provides the following performance advantages over extension methods: - Logger extension methods require "boxing" (converting) value types, such as `int`, into `object`. The pattern avoids boxing by using static fields and extension methods with strongly typed parameters. - Logger extension methods must parse the message template (named format string) every time a log message is written. only requires parsing a template once when the message is defined. @@ -43,5 +81,6 @@ Do not suppress a warning from this rule. ## See also -- [High-performance logging with LoggerMessage in ASP.NET Core](/aspnet/core/fundamentals/logging/loggermessage) +- [Compile-time logging source generation](../../../core/extensions/logger-message-generator.md) +- [High-performance logging in .NET](../../../core/extensions/high-performance-logging.md) - [Performance rules](performance-warnings.md) diff --git a/docs/standard/base-types/standard-date-and-time-format-strings.md b/docs/standard/base-types/standard-date-and-time-format-strings.md index d4dd732a0ebeb..b5bd0d22c9c42 100644 --- a/docs/standard/base-types/standard-date-and-time-format-strings.md +++ b/docs/standard/base-types/standard-date-and-time-format-strings.md @@ -17,11 +17,11 @@ ms.topic: reference --- # Standard date and time format strings -A standard date and time format string uses a single character as the format specifier to define the text representation of a or a value. Any date and time format string that contains more than one character, including white space, is interpreted as a [custom date and time format string](custom-date-and-time-format-strings.md). A standard or custom format string can be used in two ways: +A standard date and time format string uses a single character as the format specifier to define the text representation of a , , , or value. Any date and time format string that contains more than one character, including white space, is interpreted as a [custom date and time format string](custom-date-and-time-format-strings.md). A standard or custom format string can be used in two ways: - To define the string that results from a formatting operation. -- To define the text representation of a date and time value that can be converted to a or value by a parsing operation. +- To define the text representation of a date and time value that can be converted to a , , , or value by a parsing operation. > [!TIP] > You can download the **Formatting Utility**, a .NET Windows Forms application that lets you apply format strings to either numeric or date and time values and display the result string. Source code is available for [C#](/samples/dotnet/samples/windowsforms-formatting-utility-cs) and [Visual Basic](/samples/dotnet/samples/windowsforms-formatting-utility-vb). @@ -30,22 +30,22 @@ A standard date and time format string uses a single character as the format spe ## Table of format specifiers - The following table describes the standard date and time format specifiers. Unless otherwise noted, a particular standard date and time format specifier produces an identical string representation regardless of whether it is used with a or a value. See [Control Panel Settings](#control-panel-settings) and [DateTimeFormatInfo Properties](#datetimeformatinfo-properties) for additional information about using standard date and time format strings. + The following table describes the standard date and time format specifiers. Unless otherwise noted, a particular standard date and time format specifier produces an identical string representation regardless of whether it is used with a or a value. Not all format specifiers can be used with and values; for additional information, see [DateOnly and TimeOnly formatting](#dateonly-and-timeonly-formatting). For information about how regional settings on Windows and the current object can affect date and time formatting, see [Control Panel Settings](#control-panel-settings) and [DateTimeFormatInfo Properties](#datetimeformatinfo-properties). |Format specifier|Description|Examples| |----------------------|-----------------|--------------| -|"d"|Short date pattern.

More information:[The short date ("d") format specifier](#ShortDate).|2009-06-15T13:45:30 -> 6/15/2009 (en-US)

2009-06-15T13:45:30 -> 15/06/2009 (fr-FR)

2009-06-15T13:45:30 -> 2009/06/15 (ja-JP)| +|"d"|Short date pattern.

More information:[The short date ("d") format specifier](#ShortDate).|2009-06-15T13:45:30 -> 6/15/2009 (en-US)

2009-06-15T13:45:30 -> 15/06/2009 (fr-FR)

2009-06-15T13:45:30 -> 2009/06/15 (ja-JP)

(2009-06-15) -> 6/15/2009 (en-US)| |"D"|Long date pattern.

More information:[The long date ("D") format specifier](#LongDate).|2009-06-15T13:45:30 -> Monday, June 15, 2009 (en-US)

2009-06-15T13:45:30 -> понедельник, 15 июня 2009 г. (ru-RU)

2009-06-15T13:45:30 -> Montag, 15. Juni 2009 (de-DE)| |"f"|Full date/time pattern (short time).

More information: [The full date short time ("f") format specifier](#FullDateShortTime).|2009-06-15T13:45:30 -> Monday, June 15, 2009 1:45 PM (en-US)

2009-06-15T13:45:30 -> den 15 juni 2009 13:45 (sv-SE)

2009-06-15T13:45:30 -> Δευτέρα, 15 Ιουνίου 2009 1:45 μμ (el-GR)| |"F"|Full date/time pattern (long time).

More information: [The full date long time ("F") format specifier](#FullDateLongTime).|2009-06-15T13:45:30 -> Monday, June 15, 2009 1:45:30 PM (en-US)

2009-06-15T13:45:30 -> den 15 juni 2009 13:45:30 (sv-SE)

2009-06-15T13:45:30 -> Δευτέρα, 15 Ιουνίου 2009 1:45:30 μμ (el-GR)| |"g"|General date/time pattern (short time).

More information: [The general date short time ("g") format specifier](#GeneralDateShortTime).|2009-06-15T13:45:30 -> 6/15/2009 1:45 PM (en-US)

2009-06-15T13:45:30 -> 15/06/2009 13:45 (es-ES)

2009-06-15T13:45:30 -> 2009/6/15 13:45 (zh-CN)| |"G"|General date/time pattern (long time).

More information: [The general date long time ("G") format specifier](#GeneralDateLongTime).|2009-06-15T13:45:30 -> 6/15/2009 1:45:30 PM (en-US)

2009-06-15T13:45:30 -> 15/06/2009 13:45:30 (es-ES)

2009-06-15T13:45:30 -> 2009/6/15 13:45:30 (zh-CN)| |"M", "m"|Month/day pattern.

More information: [The month ("M", "m") format specifier](#MonthDay).|2009-06-15T13:45:30 -> June 15 (en-US)

2009-06-15T13:45:30 -> 15. juni (da-DK)

2009-06-15T13:45:30 -> 15 Juni (id-ID)| -|"O", "o"|round-trip date/time pattern.

More information: [The round-trip ("O", "o") format specifier](#Roundtrip).| values:

2009-06-15T13:45:30 (DateTimeKind.Local) --> 2009-06-15T13:45:30.0000000-07:00

2009-06-15T13:45:30 (DateTimeKind.Utc) --> 2009-06-15T13:45:30.0000000Z

2009-06-15T13:45:30 (DateTimeKind.Unspecified) --> 2009-06-15T13:45:30.0000000

values:

2009-06-15T13:45:30-07:00 --> 2009-06-15T13:45:30.0000000-07:00| +|"O", "o"|round-trip date/time pattern.

More information: [The round-trip ("O", "o") format specifier](#Roundtrip).| values:

2009-06-15T13:45:30 (DateTimeKind.Local) --> 2009-06-15T13:45:30.0000000-07:00

2009-06-15T13:45:30 (DateTimeKind.Utc) --> 2009-06-15T13:45:30.0000000Z

2009-06-15T13:45:30 (DateTimeKind.Unspecified) --> 2009-06-15T13:45:30.0000000

values:

2009-06-15T13:45:30-07:00 --> 2009-06-15T13:45:30.0000000-07:00

values:

2009-06-15 --> 2009-06-15

values:

13:45:30 --> 13:45:30.0000000| |"R", "r"|RFC1123 pattern.

More information: [The RFC1123 ("R", "r") format specifier](#RFC1123).| input: 2009-06-15T13:45:30 -> Mon, 15 Jun 2009 20:45:30 GMT
input: 2009-06-15T13:45:30 -> Mon, 15 Jun 2009 13:45:30 GMT | |"s"|Sortable date/time pattern.

More information: [The sortable ("s") format specifier](#Sortable).|2009-06-15T13:45:30 (DateTimeKind.Local) -> 2009-06-15T13:45:30

2009-06-15T13:45:30 (DateTimeKind.Utc) -> 2009-06-15T13:45:30| -|"t"|Short time pattern.

More information: [The short time ("t") format specifier](#ShortTime).|2009-06-15T13:45:30 -> 1:45 PM (en-US)

2009-06-15T13:45:30 -> 13:45 (hr-HR)

2009-06-15T13:45:30 -> 01:45 م (ar-EG)| -|"T"|Long time pattern.

More information: [The long time ("T") format specifier](#LongTime).|2009-06-15T13:45:30 -> 1:45:30 PM (en-US)

2009-06-15T13:45:30 -> 13:45:30 (hr-HR)

2009-06-15T13:45:30 -> 01:45:30 م (ar-EG)| +|"t"|Short time pattern.

More information: [The short time ("t") format specifier](#ShortTime).|2009-06-15T13:45:30 -> 1:45 PM (en-US)

2009-06-15T13:45:30 -> 13:45 (hr-HR)

2009-06-15T13:45:30 -> 01:45 م (ar-EG)

(13:45:30) -> 1:45 PM (en-US)| +|"T"|Long time pattern.

More information: [The long time ("T") format specifier](#LongTime).|2009-06-15T13:45:30 -> 1:45:30 PM (en-US)

2009-06-15T13:45:30 -> 13:45:30 (hr-HR)

2009-06-15T13:45:30 -> 01:45:30 م (ar-EG)

(13:45:30) -> 1:45:30 PM (en-US)| |"u"|Universal sortable date/time pattern.

More information: [The universal sortable ("u") format specifier](#UniversalSortable).|With a value: 2009-06-15T13:45:30 -> 2009-06-15 13:45:30Z

With a value: 2009-06-15T13:45:30 -> 2009-06-15 20:45:30Z| |"U"|Universal full date/time pattern.

More information: [The universal full ("U") format specifier](#UniversalFull).|2009-06-15T13:45:30 -> Monday, June 15, 2009 8:45:30 PM (en-US)

2009-06-15T13:45:30 -> den 15 juni 2009 20:45:30 (sv-SE)

2009-06-15T13:45:30 -> Δευτέρα, 15 Ιουνίου 2009 8:45:30 μμ (el-GR)| |"Y", "y"|Year month pattern.

More information: [The year month ("Y") format specifier](#YearMonth).|2009-06-15T13:45:30 -> June 2009 (en-US)

2009-06-15T13:45:30 -> juni 2009 (da-DK)

2009-06-15T13:45:30 -> Juni 2009 (id-ID)| @@ -84,12 +84,12 @@ In some cases, the standard format string serves as a convenient abbreviation fo |"s"||yyyy'-'MM'-'dd'T'HH':'mm':'ss| |"u"||yyyy'-'MM'-'dd HH':'mm':'ss'Z'| -Standard format strings can also be used in parsing operations with the or methods, which require an input string to exactly conform to a particular pattern for the parse operation to succeed. Many standard format strings map to multiple custom format strings, so a date and time value can be represented in a variety of formats and the parse operation will still succeed. You can determine the custom format string or strings that correspond to a standard format string by calling the method. The following example displays the custom format strings that map to the "d" (short date pattern) standard format string. +Standard format strings can also be used in parsing operations with the , , , and methods, which require an input string to exactly conform to a particular pattern for the parse operation to succeed. Many standard format strings map to multiple custom format strings, so a date and time value can be represented in a variety of formats and the parse operation will still succeed. You can determine the custom format string or strings that correspond to a standard format string by calling the method. The following example displays the custom format strings that map to the "d" (short date pattern) standard format string. [!code-csharp[Formatting.DateAndTime.Standard#17](../../../samples/snippets/csharp/VS_Snippets_CLR/Formatting.DateAndTime.Standard/cs/stdandparsing1.cs#17)] [!code-vb[Formatting.DateAndTime.Standard#17](../../../samples/snippets/visualbasic/VS_Snippets_CLR/Formatting.DateAndTime.Standard/vb/stdandparsing1.vb#17)] -The following sections describe the standard format specifiers for and values. +The following sections describe the standard format specifiers for , , , and values. ## Date formats @@ -256,6 +256,8 @@ The following example uses the "G" format specifier to display a date and time v The "O" or "o" standard format specifier represents a custom date and time format string using a pattern that preserves time zone information and emits a result string that complies with ISO 8601. For values, this format specifier is designed to preserve date and time values along with the property in text. The formatted string can be parsed back by using the or method if the `styles` parameter is set to . +For values, this format specifier produces a date-only ISO 8601 string in the format "yyyy-MM-dd". For values, it produces a time-only ISO 8601 string in the format "HH:mm:ss.fffffff". + The "O" or "o" standard format specifier corresponds to the "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffK" custom format string for values and to the "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffzzz" custom format string for values. In this string, the pairs of single quotation marks that delimit individual characters, such as the hyphens, the colons, and the letter "T", indicate that the individual character is a literal that cannot be changed. The apostrophes do not appear in the output string. The "O" or "o" standard format specifier (and the "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffK" custom format string) takes advantage of the three ways that ISO 8601 represents time zone information to preserve the property of values: @@ -268,7 +270,7 @@ The "O" or "o" standard format specifier (and the "yyyy'-'MM'-'dd'T'HH':'mm':'ss Because the "O" or "o" standard format specifier conforms to an international standard, the formatting or parsing operation that uses the specifier always uses the invariant culture and the Gregorian calendar. -Strings that are passed to the `Parse`, `TryParse`, `ParseExact`, and `TryParseExact` methods of and can be parsed by using the "O" or "o" format specifier if they are in one of these formats. In the case of objects, the parsing overload that you call should also include a `styles` parameter with a value of . Note that if you call a parsing method with the custom format string that corresponds to the "O" or "o" format specifier, you won't get the same results as "O" or "o". This is because parsing methods that use a custom format string can't parse the string representation of date and time values that lack a time zone component or use "Z" to indicate UTC. +Strings that are passed to the `Parse`, `TryParse`, `ParseExact`, and `TryParseExact` methods of , , , and can be parsed by using the "O" or "o" format specifier if they are in one of these formats. In the case of objects, the parsing overload that you call should also include a `styles` parameter with a value of . Note that if you call a parsing method with the custom format string that corresponds to the "O" or "o" format specifier, you won't get the same results as "O" or "o". This is because parsing methods that use a custom format string can't parse the string representation of date and time values that lack a time zone component or use "Z" to indicate UTC. The following example uses the "o" format specifier to display a series of values and a value on a system in the U.S. Pacific Time zone. @@ -463,6 +465,24 @@ The following example uses the "y" format specifier to display a date and time v +## DateOnly and TimeOnly formatting + + and types support a subset of the standard date and time format strings: + +- **** supports date-related format specifiers: + - "d" (short date), "D" (long date) + - "M" or "m" (month/day) + - "Y" or "y" (year/month) + - "O" or "o" (round-trip, date portion only) + - "R" or "r" (RFC1123, date portion only) + +- **** supports time-related format specifiers: + - "t" (short time), "T" (long time) + - "O" or "o" (round-trip, time portion only) + - "R" or "r" (RFC1123, time portion only) + +Format specifiers that combine both date and time information (such as "f", "F", "g", "G", "s", "u", "U") throw a when used with or . + ## Control Panel settings In Windows, the settings in the **Regional and Language Options** item in Control Panel influence the result string produced by a formatting operation. These settings are used to initialize the object associated with the current culture, which provides values used to govern formatting. Computers that use different settings generate different result strings. diff --git a/docs/standard/glossary.md b/docs/standard/glossary.md index d436268246d73..f4f9b6add966a 100644 --- a/docs/standard/glossary.md +++ b/docs/standard/glossary.md @@ -2,8 +2,6 @@ title: .NET glossary description: Find out the meaning of selected terms used in the .NET documentation. ms.date: 09/25/2024 -author: tdykstra -ms.author: tdykstra ms.topic: reference --- # .NET glossary diff --git a/includes/cli-add-source.md b/includes/cli-add-source.md index ea989cc0a16bb..86fddfdd65560 100644 --- a/includes/cli-add-source.md +++ b/includes/cli-add-source.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/04/2021 ms.topic: include --- diff --git a/includes/cli-advertising-manifests.md b/includes/cli-advertising-manifests.md index 78c216a0a33f2..a229b7e6ab870 100644 --- a/includes/cli-advertising-manifests.md +++ b/includes/cli-advertising-manifests.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/04/2021 ms.topic: include --- diff --git a/includes/cli-allow-downgrade.md b/includes/cli-allow-downgrade.md index 368d9eae8754f..527376e866245 100644 --- a/includes/cli-allow-downgrade.md +++ b/includes/cli-allow-downgrade.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 03/15/2024 ms.topic: include --- diff --git a/includes/cli-arch-no-a.md b/includes/cli-arch-no-a.md index 4790720de55fe..784fa28e1fc95 100644 --- a/includes/cli-arch-no-a.md +++ b/includes/cli-arch-no-a.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/12/2021 ms.topic: include --- diff --git a/includes/cli-arch.md b/includes/cli-arch.md index 0c2544fc7f4d3..5fbd636774510 100644 --- a/includes/cli-arch.md +++ b/includes/cli-arch.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/12/2021 ms.topic: include --- diff --git a/includes/cli-artifacts-path.md b/includes/cli-artifacts-path.md index 526f52019e232..510199d186977 100644 --- a/includes/cli-artifacts-path.md +++ b/includes/cli-artifacts-path.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 04/26/2024 ms.topic: include --- diff --git a/includes/cli-configfile.md b/includes/cli-configfile.md index d0785a992de61..86b94b2d09d69 100644 --- a/includes/cli-configfile.md +++ b/includes/cli-configfile.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/04/2021 ms.topic: include --- diff --git a/includes/cli-configuration-clean.md b/includes/cli-configuration-clean.md index f34be9177e474..8a1de3bf2e757 100644 --- a/includes/cli-configuration-clean.md +++ b/includes/cli-configuration-clean.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/04/2021 ms.topic: include --- diff --git a/includes/cli-configuration-publish-pack.md b/includes/cli-configuration-publish-pack.md index c1eb1e4e37f92..27ab9d97df767 100644 --- a/includes/cli-configuration-publish-pack.md +++ b/includes/cli-configuration-publish-pack.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 04/04/2024 ms.topic: include --- diff --git a/includes/cli-configuration.md b/includes/cli-configuration.md index 7784b6bd50f1e..b6fb9f60d3e99 100644 --- a/includes/cli-configuration.md +++ b/includes/cli-configuration.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/04/2021 ms.topic: include --- diff --git a/includes/cli-disable-build-servers.md b/includes/cli-disable-build-servers.md index a964b8c4b5cec..cfd168f9e8cb7 100644 --- a/includes/cli-disable-build-servers.md +++ b/includes/cli-disable-build-servers.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 07/20/2023 ms.topic: include --- diff --git a/includes/cli-disable-parallel.md b/includes/cli-disable-parallel.md index a42e924e062de..e3c3b4b2805bd 100644 --- a/includes/cli-disable-parallel.md +++ b/includes/cli-disable-parallel.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/12/2021 ms.topic: include --- diff --git a/includes/cli-help.md b/includes/cli-help.md index e6e4297f8e053..a6df485ed0528 100644 --- a/includes/cli-help.md +++ b/includes/cli-help.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/04/2021 ms.topic: include --- diff --git a/includes/cli-ignore-failed-sources.md b/includes/cli-ignore-failed-sources.md index 95148199e133e..8fa0525d7070e 100644 --- a/includes/cli-ignore-failed-sources.md +++ b/includes/cli-ignore-failed-sources.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/12/2021 ms.topic: include --- diff --git a/includes/cli-include-previews.md b/includes/cli-include-previews.md index 862c0fedaa3af..e52bb2b4ab951 100644 --- a/includes/cli-include-previews.md +++ b/includes/cli-include-previews.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/12/2021 ms.topic: include --- diff --git a/includes/cli-interactive-3-0.md b/includes/cli-interactive-3-0.md index 42a5496e57891..6a33b83f9eb33 100644 --- a/includes/cli-interactive-3-0.md +++ b/includes/cli-interactive-3-0.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/04/2021 ms.topic: include --- diff --git a/includes/cli-interactive-5-0.md b/includes/cli-interactive-5-0.md index c2a16c9ac64ed..a2189e7d91624 100644 --- a/includes/cli-interactive-5-0.md +++ b/includes/cli-interactive-5-0.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/04/2021 ms.topic: include --- diff --git a/includes/cli-interactive.md b/includes/cli-interactive.md index 95a2800134261..ae9ca355b0903 100644 --- a/includes/cli-interactive.md +++ b/includes/cli-interactive.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/04/2021 ms.topic: include --- diff --git a/includes/cli-no-cache.md b/includes/cli-no-cache.md index b4c3d1c151822..be697af28f6a9 100644 --- a/includes/cli-no-cache.md +++ b/includes/cli-no-cache.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/04/2021 ms.topic: include --- diff --git a/includes/cli-os.md b/includes/cli-os.md index bb842e766e335..17855ac9ad742 100644 --- a/includes/cli-os.md +++ b/includes/cli-os.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/12/2021 ms.topic: include --- diff --git a/includes/cli-skip-manifest-update.md b/includes/cli-skip-manifest-update.md index b9ddc27d05802..35b589638c428 100644 --- a/includes/cli-skip-manifest-update.md +++ b/includes/cli-skip-manifest-update.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/12/2021 ms.topic: include --- diff --git a/includes/cli-source.md b/includes/cli-source.md index eee61bacc62aa..a05e15cce6083 100644 --- a/includes/cli-source.md +++ b/includes/cli-source.md @@ -1,10 +1,7 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/12/2021 ms.topic: include --- - **`-s|--source `** Specifies the URI of the NuGet package source to use. This setting overrides all of the sources specified in the *nuget.config* files. Multiple sources can be provided by specifying this option multiple times. - \ No newline at end of file diff --git a/includes/cli-temp-dir.md b/includes/cli-temp-dir.md index c0160b976d65e..1f77b7a9ebfe4 100644 --- a/includes/cli-temp-dir.md +++ b/includes/cli-temp-dir.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/12/2021 ms.topic: include --- diff --git a/includes/cli-tl.md b/includes/cli-tl.md index 1aed401765fa9..3a9b8758e9c92 100644 --- a/includes/cli-tl.md +++ b/includes/cli-tl.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 11/27/2023 ms.topic: include --- diff --git a/includes/cli-verbosity-minimal.md b/includes/cli-verbosity-minimal.md index 92d5639dd1810..0eb2e8715f954 100644 --- a/includes/cli-verbosity-minimal.md +++ b/includes/cli-verbosity-minimal.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/04/2021 ms.topic: include --- diff --git a/includes/cli-verbosity-normal.md b/includes/cli-verbosity-normal.md index fe776330cea72..c84062b53ff01 100644 --- a/includes/cli-verbosity-normal.md +++ b/includes/cli-verbosity-normal.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/04/2021 ms.topic: include --- diff --git a/includes/cli-verbosity-packages.md b/includes/cli-verbosity-packages.md index 8205cbc8b0990..ed47aec11ee64 100644 --- a/includes/cli-verbosity-packages.md +++ b/includes/cli-verbosity-packages.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/04/2021 ms.topic: include --- diff --git a/includes/cli-verbosity.md b/includes/cli-verbosity.md index d1947bf0c7d3a..74879688f3bfb 100644 --- a/includes/cli-verbosity.md +++ b/includes/cli-verbosity.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/04/2021 ms.topic: include --- diff --git a/includes/cli-version.md b/includes/cli-version.md index 228317db2d433..f942869ab1c1f 100644 --- a/includes/cli-version.md +++ b/includes/cli-version.md @@ -1,6 +1,4 @@ --- -author: tdykstra -ms.author: tdykstra ms.date: 08/12/2024 ms.topic: include ---