diff --git a/docfx.json b/docfx.json
index 60d97942ea2fa..705126f1e19c5 100644
--- a/docfx.json
+++ b/docfx.json
@@ -905,6 +905,9 @@
"ms.collection": {
"docs/ai/**/**.{md,yml}": "ce-skilling-ai-copilot"
},
+ "ms.custom": {
+ "docs/ai/**/**.{md,yml}": "devx-track-dotnet"
+ },
"ms.update-cycle": {
"docs/ai/**/**.{md,yml}": "180-days",
"docs/csharp/whats-new/**/**.{md,yml}": "1095-days",
diff --git a/docs/ai/azure-ai-for-dotnet-developers.md b/docs/ai/azure-ai-for-dotnet-developers.md
index e7a822e236acf..59e100ab98a74 100644
--- a/docs/ai/azure-ai-for-dotnet-developers.md
+++ b/docs/ai/azure-ai-for-dotnet-developers.md
@@ -3,7 +3,6 @@ title: Develop .NET apps that use Azure AI services
description: This article provides an organized list of resources about Azure AI scenarios for .NET developers, including documentation and code samples.
ms.date: 05/29/2025
ms.topic: overview
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
---
# Develop AI apps with .NET
diff --git a/docs/ai/dotnet-ai-ecosystem.md b/docs/ai/dotnet-ai-ecosystem.md
index 33b4ad69bbc95..ca6b70fccfaf8 100644
--- a/docs/ai/dotnet-ai-ecosystem.md
+++ b/docs/ai/dotnet-ai-ecosystem.md
@@ -3,7 +3,6 @@ title: .NET + AI ecosystem tools and SDKs
description: This article provides an overview of the ecosystem of SDKs and tools available to .NET developers integrating AI into their applications.
ms.date: 05/29/2025
ms.topic: overview
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
---
# .NET + AI ecosystem tools and SDKs
diff --git a/docs/ai/get-started-app-chat-scaling-with-azure-container-apps.md b/docs/ai/get-started-app-chat-scaling-with-azure-container-apps.md
index dbd05f8b6ae0b..52ba3c55d2a97 100644
--- a/docs/ai/get-started-app-chat-scaling-with-azure-container-apps.md
+++ b/docs/ai/get-started-app-chat-scaling-with-azure-container-apps.md
@@ -3,7 +3,6 @@ title: Scale Azure OpenAI for .NET chat sample using RAG
description: Learn how to add load balancing to your application to extend the chat app beyond the Azure OpenAI token and model quota limits.
ms.date: 05/29/2025
ms.topic: get-started
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
# CustomerIntent: As a .NET developer new to Azure OpenAI, I want to scale my Azure OpenAI capacity to avoid rate limit errors with Azure Container Apps.
---
diff --git a/docs/ai/get-started-app-chat-template.md b/docs/ai/get-started-app-chat-template.md
index 0bb34aa5724c9..7f114fdb387f6 100644
--- a/docs/ai/get-started-app-chat-template.md
+++ b/docs/ai/get-started-app-chat-template.md
@@ -3,7 +3,6 @@ title: "Get started with the 'chat using your own data sample' for .NET"
description: Get started with .NET and search across your own data using a chat app sample implemented using Azure OpenAI Service and Retrieval Augmented Generation (RAG) in Azure AI Search. Easily deploy with Azure Developer CLI. This article uses the Azure AI Reference Template sample.
ms.date: 05/28/2025
ms.topic: get-started
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
# CustomerIntent: As a .NET developer new to Azure OpenAI, I want deploy and use sample code to interact with app infused with my own business data so that learn from the sample code.
---
diff --git a/docs/ai/get-started-mcp.md b/docs/ai/get-started-mcp.md
index 17e711a2e1842..9b39e257df3ce 100644
--- a/docs/ai/get-started-mcp.md
+++ b/docs/ai/get-started-mcp.md
@@ -3,7 +3,6 @@ title: Get started with .NET AI and MCP
description: Learn about .NET AI and MCP key concepts and development resources to get started building MCP clients and servers
ms.date: 04/29/2025
ms.topic: overview
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
author: alexwolfmsft
ms.author: alexwolf
# CustomerIntent: As a .NET developer new to OpenAI, I want deploy and use sample code to interact to learn from the sample code to summarize text.
diff --git a/docs/ai/how-to/app-service-aoai-auth.md b/docs/ai/how-to/app-service-aoai-auth.md
index 046d73677b5c1..e52ac05dcce95 100644
--- a/docs/ai/how-to/app-service-aoai-auth.md
+++ b/docs/ai/how-to/app-service-aoai-auth.md
@@ -4,7 +4,6 @@ description: "Learn how to authenticate your Azure hosted .NET app to an Azure O
author: alexwolfmsft
ms.author: alexwolf
ms.topic: how-to
-ms.custom: devx-track-azurecli
ms.date: 05/29/2025
zone_pivot_groups: azure-interface
#customer intent: As a .NET developer, I want authenticate and authorize my App Service to Azure OpenAI by using Microsoft Entra so that I can securely use AI in my .NET application.
diff --git a/docs/ai/how-to/content-filtering.md b/docs/ai/how-to/content-filtering.md
index 9e6f867ffb3ee..f3f875a9790f0 100644
--- a/docs/ai/how-to/content-filtering.md
+++ b/docs/ai/how-to/content-filtering.md
@@ -1,7 +1,6 @@
---
title: "Manage OpenAI Content Filtering in a .NET app"
description: "Learn how to manage OpenAI content filtering programmatically in a .NET app using the OpenAI client library."
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
ms.topic: how-to
ms.date: 05/29/2025
diff --git a/docs/ai/overview.md b/docs/ai/overview.md
index e6ec9365c7750..6525e19bafcb5 100644
--- a/docs/ai/overview.md
+++ b/docs/ai/overview.md
@@ -3,7 +3,6 @@ title: Develop .NET apps with AI features
description: Learn how you can build .NET applications that include AI features.
ms.date: 04/09/2025
ms.topic: overview
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
---
# Develop .NET apps with AI features
diff --git a/docs/ai/quickstarts/ai-templates.md b/docs/ai/quickstarts/ai-templates.md
index 0b6396c858ac7..c0088374eb5a5 100644
--- a/docs/ai/quickstarts/ai-templates.md
+++ b/docs/ai/quickstarts/ai-templates.md
@@ -3,7 +3,6 @@ title: Quickstart - Create a .NET AI app using the AI app template
description: Create a .NET AI app to chat with custom data using the AI app template extensions and the Microsoft.Extensions.AI libraries
ms.date: 07/30/2025
ms.topic: quickstart
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
author: alexwolfmsft
ms.author: alexwolf
zone_pivot_groups: meai-targets
diff --git a/docs/ai/quickstarts/build-chat-app.md b/docs/ai/quickstarts/build-chat-app.md
index b0792d71f5311..6d82bfe1bb17c 100644
--- a/docs/ai/quickstarts/build-chat-app.md
+++ b/docs/ai/quickstarts/build-chat-app.md
@@ -3,7 +3,6 @@ title: Quickstart - Build an AI chat app with .NET
description: Create a simple AI powered chat app using Microsoft.Extensions.AI and the OpenAI or Azure OpenAI SDKs
ms.date: 04/09/2025
ms.topic: quickstart
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
zone_pivot_groups: openai-library
# CustomerIntent: As a .NET developer new to AI, I want deploy and use sample code to interact to learn from the sample code.
---
diff --git a/docs/ai/quickstarts/build-mcp-client.md b/docs/ai/quickstarts/build-mcp-client.md
index ed4bf74b7be66..467e9df0080d7 100644
--- a/docs/ai/quickstarts/build-mcp-client.md
+++ b/docs/ai/quickstarts/build-mcp-client.md
@@ -3,7 +3,6 @@ title: Quickstart - Create a minimal MCP client using .NET
description: Learn to create a minimal MCP client and connect it to an MCP server using .NET
ms.date: 05/27/2025
ms.topic: quickstart
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
author: alexwolfmsft
---
diff --git a/docs/ai/quickstarts/build-mcp-server.md b/docs/ai/quickstarts/build-mcp-server.md
index 61761da3b867d..85c8f4fa74f7f 100644
--- a/docs/ai/quickstarts/build-mcp-server.md
+++ b/docs/ai/quickstarts/build-mcp-server.md
@@ -3,7 +3,6 @@ title: Quickstart - Create a minimal MCP server and publish to NuGet
description: Learn to create and connect to a minimal MCP server using C# and publish it to NuGet.
ms.date: 07/02/2025
ms.topic: quickstart
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
author: alexwolfmsft
ms.author: alexwolf
---
diff --git a/docs/ai/quickstarts/build-vector-search-app.md b/docs/ai/quickstarts/build-vector-search-app.md
index efc67eccf67b4..89c55cbb4df9d 100644
--- a/docs/ai/quickstarts/build-vector-search-app.md
+++ b/docs/ai/quickstarts/build-vector-search-app.md
@@ -3,7 +3,6 @@ title: Quickstart - Build a minimal .NET AI RAG app
description: Create an AI powered app to search and integrate with vector stores using embeddings and the Microsoft.Extensions.VectorData package for .NET
ms.date: 05/29/2025
ms.topic: quickstart
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
zone_pivot_groups: openai-library
# CustomerIntent: As a .NET developer new to AI, I want deploy and use sample code to interact to learn from the sample code.
---
diff --git a/docs/ai/quickstarts/chat-local-model.md b/docs/ai/quickstarts/chat-local-model.md
index edaf6683fd842..808dea2598398 100644
--- a/docs/ai/quickstarts/chat-local-model.md
+++ b/docs/ai/quickstarts/chat-local-model.md
@@ -3,7 +3,6 @@ title: Quickstart - Connect to and chat with a local AI using .NET
description: Set up a local AI model and chat with it using a .NET console app and the Microsoft.Extensions.AI libraries
ms.date: 05/28/2025
ms.topic: quickstart
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
---
# Chat with a local AI model using .NET
diff --git a/docs/ai/quickstarts/create-assistant.md b/docs/ai/quickstarts/create-assistant.md
index be96ff3431572..4f68cbbc053a0 100644
--- a/docs/ai/quickstarts/create-assistant.md
+++ b/docs/ai/quickstarts/create-assistant.md
@@ -3,7 +3,6 @@ title: Quickstart - Create a minimal AI assistant using .NET
description: Learn to create a minimal AI assistant with tooling capabilities using .NET and the Azure OpenAI SDK libraries
ms.date: 01/25/2025
ms.topic: quickstart
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
zone_pivot_groups: openai-library
---
diff --git a/docs/ai/quickstarts/evaluate-ai-response.md b/docs/ai/quickstarts/evaluate-ai-response.md
index 9c2a074dd6abd..e81bbea6c0e7f 100644
--- a/docs/ai/quickstarts/evaluate-ai-response.md
+++ b/docs/ai/quickstarts/evaluate-ai-response.md
@@ -3,7 +3,6 @@ title: Quickstart - Evaluate the quality of a model's response
description: Learn how to create an MSTest app to evaluate the AI chat response of a language model.
ms.date: 03/18/2025
ms.topic: quickstart
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
---
# Quickstart: Evaluate response quality
diff --git a/docs/ai/quickstarts/generate-images.md b/docs/ai/quickstarts/generate-images.md
index 076e0e3ce750b..37db9934c3628 100644
--- a/docs/ai/quickstarts/generate-images.md
+++ b/docs/ai/quickstarts/generate-images.md
@@ -3,7 +3,6 @@ title: Quickstart - Generate images using AI with .NET
description: Create a simple app using to generate images using .NET and the OpenAI or Azure OpenAI models.
ms.date: 04/09/2025
ms.topic: quickstart
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
zone_pivot_groups: openai-library
# CustomerIntent: As a .NET developer new to OpenAI, I want deploy and use sample code to interact to learn from the sample code to generate images.
---
diff --git a/docs/ai/quickstarts/includes/ai-templates-azure-openai.md b/docs/ai/quickstarts/includes/ai-templates-azure-openai.md
index 876c087ac0a24..8d7a4098d161e 100644
--- a/docs/ai/quickstarts/includes/ai-templates-azure-openai.md
+++ b/docs/ai/quickstarts/includes/ai-templates-azure-openai.md
@@ -1,7 +1,6 @@
---
ms.date: 2/21/2025
ms.topic: quickstart
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
author: alexwolfmsft
ms.author: alexwolf
---
diff --git a/docs/ai/quickstarts/includes/ai-templates-github-models.md b/docs/ai/quickstarts/includes/ai-templates-github-models.md
index 2baf9cf885d35..dfe02bce798a7 100644
--- a/docs/ai/quickstarts/includes/ai-templates-github-models.md
+++ b/docs/ai/quickstarts/includes/ai-templates-github-models.md
@@ -1,7 +1,6 @@
---
ms.date: 2/21/2025
ms.topic: include
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
author: alexwolfmsft
ms.author: alexwolf
---
diff --git a/docs/ai/quickstarts/includes/ai-templates-ollama.md b/docs/ai/quickstarts/includes/ai-templates-ollama.md
index ae6d9d14bc9dc..51d8eb9531368 100644
--- a/docs/ai/quickstarts/includes/ai-templates-ollama.md
+++ b/docs/ai/quickstarts/includes/ai-templates-ollama.md
@@ -1,7 +1,6 @@
---
ms.date: 2/21/2025
ms.topic: quickstart
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
author: alexwolfmsft
ms.author: alexwolf
---
diff --git a/docs/ai/quickstarts/includes/ai-templates-openai.md b/docs/ai/quickstarts/includes/ai-templates-openai.md
index 4ee41700800d8..6d0ce372f7f79 100644
--- a/docs/ai/quickstarts/includes/ai-templates-openai.md
+++ b/docs/ai/quickstarts/includes/ai-templates-openai.md
@@ -1,7 +1,6 @@
---
ms.date: 2/21/2025
ms.topic: include
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
author: alexwolfmsft
ms.author: alexwolf
---
diff --git a/docs/ai/quickstarts/prompt-model.md b/docs/ai/quickstarts/prompt-model.md
index e42b248b817e6..58bc0f781fa70 100644
--- a/docs/ai/quickstarts/prompt-model.md
+++ b/docs/ai/quickstarts/prompt-model.md
@@ -3,7 +3,6 @@ title: Quickstart - Connect to and prompt an AI model with .NET
description: Create a simple chat app using Microsoft.Extensions.AI to summarize a text.
ms.date: 05/02/2025
ms.topic: quickstart
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
zone_pivot_groups: openai-library
# CustomerIntent: As a .NET developer new to OpenAI, I want deploy and use sample code to interact to learn from the sample code to summarize text.
---
diff --git a/docs/ai/quickstarts/structured-output.md b/docs/ai/quickstarts/structured-output.md
index 7596a75410074..f68feff535f00 100644
--- a/docs/ai/quickstarts/structured-output.md
+++ b/docs/ai/quickstarts/structured-output.md
@@ -3,7 +3,6 @@ title: Quickstart - Request a response with structured output
description: Learn how to create a chat app that responds with structured output, that is, output that conforms to a type that you specify.
ms.date: 04/30/2025
ms.topic: quickstart
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
---
# Request a response with structured output
diff --git a/docs/ai/quickstarts/use-function-calling.md b/docs/ai/quickstarts/use-function-calling.md
index bfc1ee2abc36e..ca51d59d16a31 100644
--- a/docs/ai/quickstarts/use-function-calling.md
+++ b/docs/ai/quickstarts/use-function-calling.md
@@ -3,7 +3,6 @@ title: Quickstart - Extend OpenAI using Tools and execute a local Function with
description: Create a simple chat app using OpenAI and extend the model to execute a local function.
ms.date: 03/13/2025
ms.topic: quickstart
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
zone_pivot_groups: openai-library
# CustomerIntent: As a .NET developer new to OpenAI, I want deploy and use sample code to interact to learn from the sample code how to extend the model using Tools.
---
diff --git a/docs/ai/semantic-kernel-dotnet-overview.md b/docs/ai/semantic-kernel-dotnet-overview.md
index c8769c347d175..0428cfa968e15 100644
--- a/docs/ai/semantic-kernel-dotnet-overview.md
+++ b/docs/ai/semantic-kernel-dotnet-overview.md
@@ -3,7 +3,6 @@ title: Semantic Kernel overview for .NET
description: Learn how to add the Semantic Kernel SDK to your .NET projects and explore fundamental concepts
ms.date: 04/09/2025
ms.topic: quickstart
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
author: alexwolfmsft
ms.author: alexwolf
---
diff --git a/docs/ai/tutorials/evaluate-safety.md b/docs/ai/tutorials/evaluate-safety.md
index e85eb1b4bad37..6ae7fc152e7d6 100644
--- a/docs/ai/tutorials/evaluate-safety.md
+++ b/docs/ai/tutorials/evaluate-safety.md
@@ -3,7 +3,6 @@ title: Tutorial - Evaluate response safety with caching and reporting
description: Create an MSTest app that evaluates the content safety of a model's response using the evaluators in the Microsoft.Extensions.AI.Evaluation.Safety package and with caching and reporting.
ms.date: 05/12/2025
ms.topic: tutorial
-ms.custom: devx-track-dotnet-ai
---
# Tutorial: Evaluate response safety with caching and reporting
diff --git a/docs/ai/tutorials/evaluate-with-reporting.md b/docs/ai/tutorials/evaluate-with-reporting.md
index 7e24fb226c93c..9f5da35e83a77 100644
--- a/docs/ai/tutorials/evaluate-with-reporting.md
+++ b/docs/ai/tutorials/evaluate-with-reporting.md
@@ -3,7 +3,6 @@ title: Tutorial - Evaluate response quality with caching and reporting
description: Create an MSTest app to evaluate the response quality of a language model, add a custom evaluator, and learn how to use the caching and reporting features of Microsoft.Extensions.AI.Evaluation.
ms.date: 05/09/2025
ms.topic: tutorial
-ms.custom: devx-track-dotnet-ai
---
# Tutorial: Evaluate response quality with caching and reporting
diff --git a/docs/ai/tutorials/tutorial-ai-vector-search.md b/docs/ai/tutorials/tutorial-ai-vector-search.md
index 1f7be83922327..41553e0a5b8cf 100644
--- a/docs/ai/tutorials/tutorial-ai-vector-search.md
+++ b/docs/ai/tutorials/tutorial-ai-vector-search.md
@@ -3,7 +3,6 @@ title: Tutorial - Integrate OpenAI with the RAG pattern and vector search using
description: Create a simple recipe app using the RAG pattern and vector search using Azure Cosmos DB for MongoDB.
ms.date: 08/26/2025
ms.topic: tutorial
-ms.custom: devx-track-dotnet, devx-track-dotnet-ai
author: alexwolfmsft
ms.author: alexwolf
---
diff --git a/docs/azure/includes/dotnet-all.md b/docs/azure/includes/dotnet-all.md
index c417beae788bf..9b0e0305d58b1 100644
--- a/docs/azure/includes/dotnet-all.md
+++ b/docs/azure/includes/dotnet-all.md
@@ -1,13 +1,13 @@
| Name | Package | Docs | Source |
| ---- | ------- | ---- | ------ |
-| AI Agents Persistent | NuGet [1.1.0](https://www.nuget.org/packages/Azure.AI.Agents.Persistent/1.1.0)
NuGet [1.2.0-beta.3](https://www.nuget.org/packages/Azure.AI.Agents.Persistent/1.2.0-beta.3) | [docs](/dotnet/api/overview/azure/AI.Agents.Persistent-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Agents.Persistent_1.1.0/sdk/ai/Azure.AI.Agents.Persistent/)
GitHub [1.2.0-beta.3](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Agents.Persistent_1.2.0-beta.3/sdk/ai/Azure.AI.Agents.Persistent/) |
+| AI Agents Persistent | NuGet [1.1.0](https://www.nuget.org/packages/Azure.AI.Agents.Persistent/1.1.0)
NuGet [1.2.0-beta.4](https://www.nuget.org/packages/Azure.AI.Agents.Persistent/1.2.0-beta.4) | [docs](/dotnet/api/overview/azure/AI.Agents.Persistent-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Agents.Persistent_1.1.0/sdk/ai/Azure.AI.Agents.Persistent/)
GitHub [1.2.0-beta.4](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Agents.Persistent_1.2.0-beta.4/sdk/ai/Azure.AI.Agents.Persistent/) |
| AI Foundry | NuGet [1.0.0-beta.11](https://www.nuget.org/packages/Azure.AI.Projects/1.0.0-beta.11) | [docs](/dotnet/api/overview/azure/AI.Projects-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.11](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Projects_1.0.0-beta.11/sdk/ai/Azure.AI.Projects/) |
| AI Model Inference | NuGet [1.0.0-beta.5](https://www.nuget.org/packages/Azure.AI.Inference/1.0.0-beta.5) | [docs](/dotnet/api/overview/azure/AI.Inference-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.5](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Inference_1.0.0-beta.5/sdk/ai/Azure.AI.Inference/) |
| Anomaly Detector | NuGet [3.0.0-preview.7](https://www.nuget.org/packages/Azure.AI.AnomalyDetector/3.0.0-preview.7) | [docs](/dotnet/api/overview/azure/AI.AnomalyDetector-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [3.0.0-preview.7](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.AnomalyDetector_3.0.0-preview.7/sdk/anomalydetector/Azure.AI.AnomalyDetector/) |
| App Configuration | NuGet [1.6.1](https://www.nuget.org/packages/Azure.Data.AppConfiguration/1.6.1) | [docs](/dotnet/api/overview/azure/Data.AppConfiguration-readme) | GitHub [1.6.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Data.AppConfiguration_1.6.1/sdk/appconfiguration/Azure.Data.AppConfiguration/) |
| App Configuration Provider | NuGet [8.3.0](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.AzureAppConfiguration/8.3.0) | [docs](/dotnet/api/overview/azure/Microsoft.Extensions.Configuration.AzureAppConfiguration-readme) | GitHub [8.3.0](https://github.com/Azure/AppConfiguration-DotnetProvider) |
| Attestation | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Security.Attestation/1.0.0) | [docs](/dotnet/api/overview/azure/Security.Attestation-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Security.Attestation_1.0.0/sdk/attestation/Azure.Security.Attestation/) |
-| Azure AI Search | NuGet [11.6.1](https://www.nuget.org/packages/Azure.Search.Documents/11.6.1)
NuGet [11.7.0-beta.6](https://www.nuget.org/packages/Azure.Search.Documents/11.7.0-beta.6) | [docs](/dotnet/api/overview/azure/Search.Documents-readme) | GitHub [11.6.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Search.Documents_11.6.1/sdk/search/Azure.Search.Documents/)
GitHub [11.7.0-beta.6](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Search.Documents_11.7.0-beta.6/sdk/search/Azure.Search.Documents/) |
+| Azure AI Search | NuGet [11.6.1](https://www.nuget.org/packages/Azure.Search.Documents/11.6.1)
NuGet [11.7.0-beta.7](https://www.nuget.org/packages/Azure.Search.Documents/11.7.0-beta.7) | [docs](/dotnet/api/overview/azure/Search.Documents-readme) | GitHub [11.6.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Search.Documents_11.6.1/sdk/search/Azure.Search.Documents/)
GitHub [11.7.0-beta.7](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Search.Documents_11.7.0-beta.7/sdk/search/Azure.Search.Documents/) |
| Azure Object Anchors Conversion | NuGet [0.3.0-beta.6](https://www.nuget.org/packages/Azure.MixedReality.ObjectAnchors.Conversion/0.3.0-beta.6) | [docs](/dotnet/api/overview/azure/MixedReality.ObjectAnchors.Conversion-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [0.3.0-beta.6](https://github.com/Azure/azure-sdk-for-net/tree/Azure.MixedReality.ObjectAnchors.Conversion_0.3.0-beta.6/sdk/objectanchors/Azure.MixedReality.ObjectAnchors.Conversion/) |
| Azure Remote Rendering | NuGet [1.1.0](https://www.nuget.org/packages/Azure.MixedReality.RemoteRendering/1.1.0) | [docs](/dotnet/api/overview/azure/MixedReality.RemoteRendering-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.MixedReality.RemoteRendering_1.1.0/sdk/remoterendering/Azure.MixedReality.RemoteRendering/) |
| Azure.Core.Expressions.DataFactory | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Core.Expressions.DataFactory/1.0.0) | [docs](/dotnet/api/overview/azure/Core.Expressions.DataFactory-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core.Expressions.DataFactory_1.0.0/sdk/core/Azure.Core.Expressions.DataFactory/) |
@@ -392,7 +392,7 @@
| App Configuration Extension | NuGet [8.3.0](https://www.nuget.org/packages/Microsoft.Azure.AppConfiguration.Functions.Worker/8.3.0) | | |
| App Configuration Provider | NuGet [8.3.0](https://www.nuget.org/packages/Microsoft.Azure.AppConfiguration.AspNetCore/8.3.0) | | |
| Azure.Communication.Administration | NuGet [1.0.0-beta.3](https://www.nuget.org/packages/Azure.Communication.Administration/1.0.0-beta.3) | | |
-| Communication Calling Windows Client | NuGet [1.12.0](https://www.nuget.org/packages/Azure.Communication.Calling.WindowsClient/1.12.0) | | |
+| Communication Calling Windows Client | NuGet [1.12.0](https://www.nuget.org/packages/Azure.Communication.Calling.WindowsClient/1.12.0)
NuGet [1.13.0-beta.1](https://www.nuget.org/packages/Azure.Communication.Calling.WindowsClient/1.13.0-beta.1) | | |
| Content Safety Extension Embedded Image | NuGet [1.0.1-beta.4](https://www.nuget.org/packages/Azure.AI.ContentSafety.Extension.Embedded.Image/1.0.1-beta.4) | | |
| Content Safety Extension Embedded Text | NuGet [1.0.0](https://www.nuget.org/packages/Azure.AI.ContentSafety.Extension.Embedded.Text/1.0.0)
NuGet [1.0.1-beta.4](https://www.nuget.org/packages/Azure.AI.ContentSafety.Extension.Embedded.Text/1.0.1-beta.4) | | |
| Cosmos DB Fault Injection | NuGet [1.0.0-beta.0](https://www.nuget.org/packages/Microsoft.Azure.Cosmos.FaultInjection/1.0.0-beta.0) | | |
diff --git a/docs/azure/includes/dotnet-new.md b/docs/azure/includes/dotnet-new.md
index 18dd68cfa4907..1aa1182327901 100644
--- a/docs/azure/includes/dotnet-new.md
+++ b/docs/azure/includes/dotnet-new.md
@@ -1,13 +1,13 @@
| Name | Package | Docs | Source |
| ---- | ------- | ---- | ------ |
-| AI Agents Persistent | NuGet [1.1.0](https://www.nuget.org/packages/Azure.AI.Agents.Persistent/1.1.0)
NuGet [1.2.0-beta.3](https://www.nuget.org/packages/Azure.AI.Agents.Persistent/1.2.0-beta.3) | [docs](/dotnet/api/overview/azure/AI.Agents.Persistent-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Agents.Persistent_1.1.0/sdk/ai/Azure.AI.Agents.Persistent/)
GitHub [1.2.0-beta.3](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Agents.Persistent_1.2.0-beta.3/sdk/ai/Azure.AI.Agents.Persistent/) |
+| AI Agents Persistent | NuGet [1.1.0](https://www.nuget.org/packages/Azure.AI.Agents.Persistent/1.1.0)
NuGet [1.2.0-beta.4](https://www.nuget.org/packages/Azure.AI.Agents.Persistent/1.2.0-beta.4) | [docs](/dotnet/api/overview/azure/AI.Agents.Persistent-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Agents.Persistent_1.1.0/sdk/ai/Azure.AI.Agents.Persistent/)
GitHub [1.2.0-beta.4](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Agents.Persistent_1.2.0-beta.4/sdk/ai/Azure.AI.Agents.Persistent/) |
| AI Foundry | NuGet [1.0.0-beta.11](https://www.nuget.org/packages/Azure.AI.Projects/1.0.0-beta.11) | [docs](/dotnet/api/overview/azure/AI.Projects-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.11](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Projects_1.0.0-beta.11/sdk/ai/Azure.AI.Projects/) |
| AI Model Inference | NuGet [1.0.0-beta.5](https://www.nuget.org/packages/Azure.AI.Inference/1.0.0-beta.5) | [docs](/dotnet/api/overview/azure/AI.Inference-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.5](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Inference_1.0.0-beta.5/sdk/ai/Azure.AI.Inference/) |
| Anomaly Detector | NuGet [3.0.0-preview.7](https://www.nuget.org/packages/Azure.AI.AnomalyDetector/3.0.0-preview.7) | [docs](/dotnet/api/overview/azure/AI.AnomalyDetector-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [3.0.0-preview.7](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.AnomalyDetector_3.0.0-preview.7/sdk/anomalydetector/Azure.AI.AnomalyDetector/) |
| App Configuration | NuGet [1.6.1](https://www.nuget.org/packages/Azure.Data.AppConfiguration/1.6.1) | [docs](/dotnet/api/overview/azure/Data.AppConfiguration-readme) | GitHub [1.6.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Data.AppConfiguration_1.6.1/sdk/appconfiguration/Azure.Data.AppConfiguration/) |
| App Configuration Provider | NuGet [8.3.0](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.AzureAppConfiguration/8.3.0) | [docs](/dotnet/api/overview/azure/Microsoft.Extensions.Configuration.AzureAppConfiguration-readme) | GitHub [8.3.0](https://github.com/Azure/AppConfiguration-DotnetProvider) |
| Attestation | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Security.Attestation/1.0.0) | [docs](/dotnet/api/overview/azure/Security.Attestation-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Security.Attestation_1.0.0/sdk/attestation/Azure.Security.Attestation/) |
-| Azure AI Search | NuGet [11.6.1](https://www.nuget.org/packages/Azure.Search.Documents/11.6.1)
NuGet [11.7.0-beta.6](https://www.nuget.org/packages/Azure.Search.Documents/11.7.0-beta.6) | [docs](/dotnet/api/overview/azure/Search.Documents-readme) | GitHub [11.6.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Search.Documents_11.6.1/sdk/search/Azure.Search.Documents/)
GitHub [11.7.0-beta.6](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Search.Documents_11.7.0-beta.6/sdk/search/Azure.Search.Documents/) |
+| Azure AI Search | NuGet [11.6.1](https://www.nuget.org/packages/Azure.Search.Documents/11.6.1)
NuGet [11.7.0-beta.7](https://www.nuget.org/packages/Azure.Search.Documents/11.7.0-beta.7) | [docs](/dotnet/api/overview/azure/Search.Documents-readme) | GitHub [11.6.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Search.Documents_11.6.1/sdk/search/Azure.Search.Documents/)
GitHub [11.7.0-beta.7](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Search.Documents_11.7.0-beta.7/sdk/search/Azure.Search.Documents/) |
| Azure Object Anchors Conversion | NuGet [0.3.0-beta.6](https://www.nuget.org/packages/Azure.MixedReality.ObjectAnchors.Conversion/0.3.0-beta.6) | [docs](/dotnet/api/overview/azure/MixedReality.ObjectAnchors.Conversion-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [0.3.0-beta.6](https://github.com/Azure/azure-sdk-for-net/tree/Azure.MixedReality.ObjectAnchors.Conversion_0.3.0-beta.6/sdk/objectanchors/Azure.MixedReality.ObjectAnchors.Conversion/) |
| Azure Remote Rendering | NuGet [1.1.0](https://www.nuget.org/packages/Azure.MixedReality.RemoteRendering/1.1.0) | [docs](/dotnet/api/overview/azure/MixedReality.RemoteRendering-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.MixedReality.RemoteRendering_1.1.0/sdk/remoterendering/Azure.MixedReality.RemoteRendering/) |
| Azure.Core.Expressions.DataFactory | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Core.Expressions.DataFactory/1.0.0) | [docs](/dotnet/api/overview/azure/Core.Expressions.DataFactory-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core.Expressions.DataFactory_1.0.0/sdk/core/Azure.Core.Expressions.DataFactory/) |
diff --git a/docs/core/compatibility/10.0.md b/docs/core/compatibility/10.0.md
index b20300bcb804a..4e5618060e500 100644
--- a/docs/core/compatibility/10.0.md
+++ b/docs/core/compatibility/10.0.md
@@ -45,11 +45,12 @@ If you're migrating an app to .NET 10, the breaking changes listed here might af
| [Default trace context propagator updated to W3C standard](core-libraries/10.0/default-trace-context-propagator.md) | Behavioral change | Preview 4 |
| [DriveInfo.DriveFormat returns Linux filesystem types](core-libraries/10.0/driveinfo-driveformat-linux.md) | Behavioral change | Preview 6 |
| [DynamicallyAccessedMembers annotation removed from DefaultValueAttribute ctor](core-libraries/10.0/defaultvalueattribute-dynamically-accessed-members.md) | Binary/source incompatible | Preview 7 |
+| [Explicit struct Size disallowed with InlineArray](core-libraries/10.0/inlinearray-explicit-size-disallowed.md) | Binary incompatible | Preview 7 |
+| [FilePatternMatch.Stem changed to non-nullable](core-libraries/10.0/filepatternmatch-stem-nonnullable.md) | Source incompatible/behavioral change | RC 1 |
| [GnuTarEntry and PaxTarEntry no longer includes atime and ctime by default](core-libraries/10.0/tar-atime-ctime-default.md) | Behavioral change | Preview 5 |
| [LDAP DirectoryControl parsing is now more stringent](core-libraries/10.0/ldap-directorycontrol-parsing.md) | Behavioral change | Preview 1 |
| [MacCatalyst version normalization](core-libraries/10.0/maccatalyst-version-normalization.md) | Behavioral change | Preview 1 |
| [.NET runtime no longer provides default termination signal handlers](core-libraries/10.0/sigterm-signal-handler.md) | Behavioral change | Preview 5 |
-| [Explicit struct Size disallowed with InlineArray](core-libraries/10.0/inlinearray-explicit-size-disallowed.md) | Binary incompatible | Preview 7 |
| [System.Linq.AsyncEnumerable included in core libraries](core-libraries/10.0/asyncenumerable.md) | Source incompatible | Preview 1 |
| [YMM embedded rounding removed from AVX10.2](core-libraries/10.0/ymm-embedded-rounding.md) | Behavioral change | Preview 5 |
diff --git a/docs/core/compatibility/core-libraries/10.0/filepatternmatch-stem-nonnullable.md b/docs/core/compatibility/core-libraries/10.0/filepatternmatch-stem-nonnullable.md
new file mode 100644
index 0000000000000..8dce9c0f851a0
--- /dev/null
+++ b/docs/core/compatibility/core-libraries/10.0/filepatternmatch-stem-nonnullable.md
@@ -0,0 +1,58 @@
+---
+title: "Breaking change - FilePatternMatch.Stem changed to non-nullable"
+description: "Learn about the breaking change in .NET 10 where FilePatternMatch.Stem property was changed from nullable to non-nullable."
+ms.date: 09/08/2025
+ai-usage: ai-assisted
+ms.custom: https://github.com/dotnet/docs/issues/47914
+---
+
+# FilePatternMatch.Stem changed to non-nullable
+
+The property was previously annotated as nullable because the `PatternTestResult.Stem` property it gets its value from is nullable. While the can indeed be null if the result isn't successful, the `FilePatternMatch` never is because it's only constructed when `PatternTestResult` is successful.
+
+To accurately reflect nullability, the `[MemberNotNullWhen()]` attribute is applied to the `PatternTestResult.Stem` property to tell the compiler it won't be null if it's successful. Additionally, the `stem` argument passed into the `FilePatternMatch` constructor is no longer nullable, and an `ArgumentNullException` will be thrown if a null `stem` is passed in.
+
+## Version introduced
+
+.NET 10 RC 1
+
+## Previous behavior
+
+Previously, the constructor accepted `null` for the `stem` parameter without any compile-time or run-time warnings or errors.
+
+```csharp
+// Allowed in previous versions.
+var match = new FilePatternMatch("path/to/file.txt", null);
+```
+
+The property was also annotated as being nullable.
+
+## New behavior
+
+Starting in .NET 10, passing a `null` or possibly-null value to the `stem` argument in the constructor yields a compile-time warning. And, if `null` is passed in, a run-time is thrown.
+
+The property is now annotated to indicate that the value won't be null if `IsSuccessful` is `true`.
+
+```csharp
+// Generates compile-time warning.
+var match = new FilePatternMatch("path/to/file.txt", null);
+```
+
+## Type of breaking change
+
+This change can affect [source compatibility](../../categories.md#source-compatibility) and is a [behavioral change](../../categories.md#behavioral-change).
+
+## Reason for change
+
+The previous nullability annotations were inaccurate, and a `null` value for the `stem` argument was unexpected but not properly guarded against. This change reflects the expected behavior of the API and guards against unpredictable behavior while also producing design-time guidance around usage.
+
+## Recommended action
+
+If a possibly null value was passed in for the `stem` argument, review usage and update the call site to ensure `stem` can't be paTssed in as `null`.
+
+If you applied nullability warning suppressions when consuming the `FilePatternMatch.Stem` property, you can remove those suppressions.
+
+## Affected APIs
+
+- [FilePatternMatch(String,String) constructor](xref:Microsoft.Extensions.FileSystemGlobbing.FilePatternMatch.%23ctor(System.String,System.String))
+-
diff --git a/docs/core/compatibility/toc.yml b/docs/core/compatibility/toc.yml
index 2308812e76ac7..e3a848bbafc0e 100644
--- a/docs/core/compatibility/toc.yml
+++ b/docs/core/compatibility/toc.yml
@@ -48,6 +48,10 @@ items:
href: core-libraries/10.0/driveinfo-driveformat-linux.md
- name: DynamicallyAccessedMembers annotation removed from DefaultValueAttribute ctor
href: core-libraries/10.0/defaultvalueattribute-dynamically-accessed-members.md
+ - name: Explicit struct Size disallowed with InlineArray
+ href: core-libraries/10.0/inlinearray-explicit-size-disallowed.md
+ - name: FilePatternMatch.Stem changed to non-nullable
+ href: core-libraries/10.0/filepatternmatch-stem-nonnullable.md
- name: GnuTarEntry and PaxTarEntry exclude atime and ctime by default
href: core-libraries/10.0/tar-atime-ctime-default.md
- name: LDAP DirectoryControl parsing is now more stringent
@@ -56,8 +60,6 @@ items:
href: core-libraries/10.0/maccatalyst-version-normalization.md
- name: No default termination signal handlers
href: core-libraries/10.0/sigterm-signal-handler.md
- - name: Explicit struct Size disallowed with InlineArray
- href: core-libraries/10.0/inlinearray-explicit-size-disallowed.md
- name: System.Linq.AsyncEnumerable included in core libraries
href: core-libraries/10.0/asyncenumerable.md
- name: YMM embedded rounding removed from AVX10.2
diff --git a/docs/core/extensions/dependency-injection.md b/docs/core/extensions/dependency-injection.md
index 62b3dee84cf4f..88e4007c9f6fb 100644
--- a/docs/core/extensions/dependency-injection.md
+++ b/docs/core/extensions/dependency-injection.md
@@ -81,7 +81,7 @@ The host contains the dependency injection service provider. It also contains al
By using the DI pattern, the worker service:
-- Doesn't use the concrete type `MessageWriter`, only the `IMessageWriter` interface that implements it. That makes it easy to change the implementation that the worker service uses without modifying the worker service.
+- Doesn't use the concrete type `MessageWriter`, only the `IMessageWriter` interface that it implements. That makes it easy to change the implementation that the worker service uses without modifying the worker service.
- Doesn't create an instance of `MessageWriter`. The instance is created by the DI container.
The implementation of the `IMessageWriter` interface can be improved by using the built-in logging API:
diff --git a/docs/core/tools/dotnet-new-sdk-templates.md b/docs/core/tools/dotnet-new-sdk-templates.md
index 31e82674fecaf..2557ecf8a3dd4 100644
--- a/docs/core/tools/dotnet-new-sdk-templates.md
+++ b/docs/core/tools/dotnet-new-sdk-templates.md
@@ -1,6 +1,6 @@
---
-title: .NET default templates for dotnet new
-description: The information about dotnet new templates shipped with dotnet SDK.
+title: .NET default templates for 'dotnet new'
+description: Learn about 'dotnet new' templates that ship with the .NET SDK.
ms.custom: updateeachrelease
no-loc: [Blazor, WebAssembly]
ms.date: 08/29/2025
@@ -13,15 +13,57 @@ When you install the [.NET SDK](https://dotnet.microsoft.com/download), you rece
dotnet new list
```
-[!INCLUDE [templates](../../../includes/templates.md)]
-
## Template options
-Each template may have additional options available. To show the additional options available for the template use the `--help` option with the template name argument, for example: `dotnet new console --help`.
-In case the template supports multiple languages, this command will show help for the template in the default language. By combining it with the `--language` option, you can see the help for other languages: `dotnet new console --help --language F#`.
-The templates that ship with the .NET SDK have additional options that are described in the following sections.
-
-## `buildprops`
+The templates that ship with the .NET SDK has template-specific options. To show the additional options available for the template, use the `--help` option with the template name argument, for example: `dotnet new console --help`. The template-specific sections in this article also describe the options.
+
+If the template supports multiple programming languages, the `--help` option will show help for the template in the default language. By combining it with the `--language` option, you can see the help for other languages: `dotnet new console --help --language F#`.
+
+## Preinstalled templates
+
+The following table shows the templates that come preinstalled with the .NET SDK. The default language for the template is shown inside brackets. To see any template-specific options, select the short name link.
+
+| Templates | Short name | Language | Tags | Introduced |
+|-----------------------------|-----------------------------------|----------|-------------------------|------------|
+| ASP.NET Core API | [`webapiaot`](#webapiaot) | [C#] | Web/Web API/API/Service | 8.0 |
+| ASP.NET Core API controller | [`apicontroller`](#apicontroller) | [C#] | Web/ASP.NET | 8.0 |
+| ASP.NET Core Empty | [`web`](#web) | [C#], F# | Web/Empty | 1.0 |
+| ASP.NET Core Web API | [`webapi`](#webapi) | [C#], F# | Web/Web API/API/Service/WebAPI | 1.0 |
+| ASP.NET Core Web App (Model-View-Controller) | [`mvc`](#web-options) | [C#], F# | Web/MVC | 1.0 |
+| ASP.NET Core Web App | [`webapp, razor`](#web-options) | [C#] | Web/MVC/Razor Pages | 2.2, 2.0 |
+| ASP.NET Core gRPC Service | [`grpc`](#web-others) | [C#] | Web/gRPC | 3.0 |
+| Blazor Web App | [`blazor`](#blazor) | [C#] | Web/Blazor | 8.0.100 |
+| Blazor WebAssembly Standalone App | [`blazorwasm`](#blazorwasm) | [C#] | Web/Blazor/WebAssembly/PWA | 3.1.300 |
+| Class library | [`classlib`](#classlib) | [C#], F#, VB | Common/Library | 1.0 |
+| Console Application | [`console`](#console) | [C#], F#, VB | Common/Console | 1.0 |
+| Directory.Build.props file | [`buildprops`](#buildprops) | | Config | 8.0.100 |
+| Directory.Build.targets file | [`buildtargets`](#buildtargets) | | Config | 8.0.100 |
+| Dotnet local tool manifest file | `tool-manifest` | | Config | 3.0 |
+| EditorConfig file | [`editorconfig`](#editorconfig) | | Config | 6.0 |
+| global.json file | [`globaljson`](#globaljson) | | Config | 2.0 |
+| MSTest Test Class | [`mstest-class`](#mstest-class) | [C#], F#, VB | Test/MSTest | 1.0 |
+| MSTest Test Project | [`mstest`](#mstest) | [C#], F#, VB | Test/MSTest | 1.0 |
+| NUnit 3 Test Item | `nunit-test` | [C#], F#, VB | Test/NUnit | 2.2 |
+| NUnit 3 Test Project | [`nunit`](#nunit) | [C#], F#, VB | Test/NUnit | 2.1.400 |
+| NuGet Config | `nugetconfig` | | Config | 1.0 |
+| Protocol Buffer File | [`proto`](#namespace) | | Web/gRPC | 3.0 |
+| Razor Class Library | [`razorclasslib`](#razorclasslib) | [C#] | Web/Razor/Library/Razor Class Library | 2.1 |
+| Razor Component | `razorcomponent` | [C#] | Web/ASP.NET | 3.0 |
+| Razor Page | [`page`](#page) | [C#] | Web/ASP.NET | 2.0 |
+| Solution File | [`sln`](#sln) | | Solution | 1.0 |
+| Web Config | `webconfig` | | Config | 1.0 |
+| Windows Forms (WinForms) Application | [`winforms`](#winforms) | [C#], VB | Common/WinForms | 3.0 (5.0 for VB) |
+| Windows Forms (WinForms) Class library | [`winformslib`](#winforms) | [C#], VB | Common/WinForms | 3.0 (5.0 for VB) |
+| Worker Service | [`worker`](#web-others) | [C#] | Common/Worker/Web | 3.0 |
+| WPF Application | [`wpf`](#wpf) | [C#], VB | Common/WPF | 3.0 (5.0 for VB) |
+| WPF Class library | [`wpflib`](#wpf) | [C#], VB | Common/WPF | 3.0 (5.0 for VB) |
+| WPF Custom Control Library | [`wpfcustomcontrollib`](#wpf) | [C#], VB | Common/WPF | 3.0 (5.0 for VB) |
+| WPF User Control Library | [`wpfusercontrollib`](#wpf) | [C#], VB | Common/WPF | 3.0 (5.0 for VB) |
+| xUnit Test Project | [`xunit`](#xunit) | [C#], F#, VB | Test/xUnit | 1.0 |
+| MVC ViewImports | [`viewimports`](#namespace) | [C#] | Web/ASP.NET | 2.0 |
+| MVC ViewStart | `viewstart` | [C#] | Web/ASP.NET | 2.0 |
+
+### `buildprops`
Creates a *Directory.Build.props* file for customizing MSBuild properties for an entire folder tree. For more information, see [Customize your build](/visualstudio/msbuild/customize-your-build).
@@ -35,7 +77,7 @@ Creates a *Directory.Build.props* file for customizing MSBuild properties for an
***
-## `buildtargets`
+### `buildtargets`
Creates a *Directory.Build.targets* file for customizing MSBuild targets and tasks for an entire folder tree. For more information, see [Customize your build](/visualstudio/msbuild/customize-your-build).
@@ -45,7 +87,7 @@ Creates a *Directory.Build.targets* file for customizing MSBuild targets and tas
***
-## `console`
+### `console`
- **`-f|--framework `**
@@ -53,11 +95,11 @@ Creates a *Directory.Build.targets* file for customizing MSBuild targets and tas
The following table lists the default values according to the SDK version you're using:
- | SDK version | Default value |
- |-------------|-----------------|
- | 9.0 | `net9.0` |
- | 8.0 | `net8.0` |
- | 7.0 | `net7.0` |
+ | SDK version | Default value |
+ |-------------|---------------|
+ | 9.0 | `net9.0` |
+ | 8.0 | `net8.0` |
+ | 7.0 | `net7.0` |
The ability to create a project for an earlier TFM depends on having that version of the SDK installed. For example, if you have only the .NET 9 SDK installed, then the only value available for `--framework` is `net9.0`. If, for example, you install the .NET 8 SDK, the value `net8.0` becomes available for `--framework`. So by specifying `--framework net8.0` you can target .NET 8 even while running `dotnet new` in the .NET 9 SDK.
@@ -79,7 +121,7 @@ Creates a *Directory.Build.targets* file for customizing MSBuild targets and tas
***
-## `classlib`
+### `classlib`
- **`-f|--framework `**
@@ -99,7 +141,7 @@ Creates a *Directory.Build.targets* file for customizing MSBuild targets and tas
***
-## `wpf`, `wpflib`, `wpfcustomcontrollib`, `wpfusercontrollib`
+### `wpf`, `wpflib`, `wpfcustomcontrollib`, `wpfusercontrollib`
- **`-f|--framework `**
@@ -117,7 +159,7 @@ Creates a *Directory.Build.targets* file for customizing MSBuild targets and tas
***
-## `winforms`, `winformslib`
+### `winforms`, `winformslib`
- **`--langVersion `**
@@ -131,7 +173,7 @@ Creates a *Directory.Build.targets* file for customizing MSBuild targets and tas
***
-## `worker`, `grpc`
+### `worker`, `grpc`
- **`-f|--framework `**
@@ -153,7 +195,7 @@ Creates a *Directory.Build.targets* file for customizing MSBuild targets and tas
***
-## `mstest`
+### `mstest`
- **`-f|--framework `**
@@ -161,11 +203,11 @@ Creates a *Directory.Build.targets* file for customizing MSBuild targets and tas
The following table lists the default values according to the SDK version number you're using:
- | SDK version | Default value |
- |-------------|-----------------|
- | 9.0 | `net9.0` |
- | 8.0 | `net8.0` |
- | 7.0 | `net7.0` |
+ | SDK version | Default value |
+ |-------------|---------------|
+ | 9.0 | `net9.0` |
+ | 8.0 | `net8.0` |
+ | 7.0 | `net7.0` |
The ability to create a project for an earlier TFM depends on having that version of the SDK installed. For example, if you have only the .NET 9 SDK installed, then the only value available for `--framework` is `net9.0`. If you install, for example, the .NET 8 SDK, the value `net8.0` becomes available for `--framework`. So by specifying `--framework net8.0` you can target .NET 8 even while running `dotnet new` in the .NET 9 SDK.
@@ -219,7 +261,7 @@ The ability to create a project for an earlier TFM depends on having that versio
***
-## `mstest-class`
+### `mstest-class`
- **`--fixture `**
@@ -237,7 +279,7 @@ The ability to create a project for an earlier TFM depends on having that versio
***
-## `xunit`
+### `xunit`
- **`-f|--framework `**
@@ -245,11 +287,11 @@ The ability to create a project for an earlier TFM depends on having that versio
The following table lists the default values according to the SDK version number you're using:
- | SDK version | Default value |
- |-------------|-----------------|
- | 9.0 | `net9.0` |
- | 8.0 | `net8.0` |
- | 7.0 | `net7.0` |
+ | SDK version | Default value |
+ |-------------|---------------|
+ | 9.0 | `net9.0` |
+ | 8.0 | `net8.0` |
+ | 7.0 | `net7.0` |
The ability to create a project for an earlier TFM depends on having that version of the SDK installed. For example, if you have only the .NET 9 SDK installed, then the only value available for `--framework` is `net9.0`. If you install, for example, the .NET 8 SDK, the value `net8.0` becomes available for `--framework`. So by specifying `--framework net8.0` you can target .NET 8 even while running `dotnet new` in the .NET 9 SDK.
@@ -263,7 +305,7 @@ The ability to create a project for an earlier TFM depends on having that versio
***
-## `nunit`
+### `nunit`
- **`-f|--framework `**
@@ -271,11 +313,11 @@ The ability to create a project for an earlier TFM depends on having that versio
The following table lists the default values according to the SDK version number you're using:
- | SDK version | Default value |
- |-------------|-----------------|
- | 9.0 | `net9.0` |
- | 8.0 | `net8.0` |
- | 7.0 | `net7.0` |
+ | SDK version | Default value |
+ |-------------|---------------|
+ | 9.0 | `net9.0` |
+ | 8.0 | `net8.0` |
+ | 7.0 | `net7.0` |
The ability to create a project for an earlier TFM depends on having that version of the SDK installed. For example, if you have only the .NET 9 SDK installed, then the only value available for `--framework` is `net9.0`. If you install, for example, the .NET 8 SDK, the value `net8.0` becomes available for `--framework`. So by specifying `--framework net8.0` you can target .NET 8 even while running `dotnet new` in the .NET 9 SDK.
@@ -289,7 +331,7 @@ The ability to create a project for an earlier TFM depends on having that versio
***
-## `page`
+### `page`
- **`-na|--namespace `**
@@ -301,7 +343,7 @@ The ability to create a project for an earlier TFM depends on having that versio
***
-## `viewimports`, `proto`
+### `viewimports`, `proto`
- **`-na|--namespace `**
@@ -309,92 +351,7 @@ The ability to create a project for an earlier TFM depends on having that versio
***
-## `blazorserver`
-
-**Discontinued since .NET 8 SDK.**
-
-- **`-au|--auth `**
-
- The type of authentication to use. The possible values are:
-
- - `None` - No authentication (Default).
- - `Individual` - Individual authentication.
- - `IndividualB2C` - Individual authentication with Azure AD B2C.
- - `SingleOrg` - Organizational authentication for a single tenant. [Entra External ID](/entra/external-id/) tenants also use `SingleOrg`.
- - `MultiOrg` - Organizational authentication for multiple tenants.
- - `Windows` - Windows authentication.
-
-- **`--aad-b2c-instance `**
-
- The Azure Active Directory B2C instance to connect to. Use with `IndividualB2C` authentication. The default value is `https://login.microsoftonline.com/tfp/`.
-
-- **`-ssp|--susi-policy-id `**
-
- The sign-in and sign-up policy ID for this project. Use with `IndividualB2C` authentication.
-
-- **`-rp|--reset-password-policy-id `**
-
- The reset password policy ID for this project. Use with `IndividualB2C` authentication.
-
-- **`-ep|--edit-profile-policy-id `**
-
- The edit profile policy ID for this project. Use with `IndividualB2C` authentication.
-
-- **`--aad-instance `**
-
- The Azure Active Directory instance to connect to. Use with `SingleOrg` or `MultiOrg` authentication. The default value is `https://login.microsoftonline.com/`.
-
-- **`--client-id `**
-
- The Client ID for this project. Use with `IndividualB2C`, `SingleOrg`, or `MultiOrg` authentication. The default value is `11111111-1111-1111-11111111111111111`.
-
-- **`--domain `**
-
- The domain for the directory tenant. Use with `SingleOrg` or `IndividualB2C` authentication. The default value is `qualified.domain.name`.
-
-- **`--tenant-id `**
-
- The TenantId ID of the directory to connect to. Use with `SingleOrg` authentication. The default value is `22222222-2222-2222-2222-222222222222`.
-
-- **`--callback-path `**
-
- The request path within the application's base path of the redirect URI. Use with `SingleOrg` or `IndividualB2C` authentication. The default value is `/signin-oidc`.
-
-- **`-r|--org-read-access`**
-
- Allows this application read-access to the directory. Only applies to `SingleOrg` or `MultiOrg` authentication.
-
-- **`--exclude-launch-settings`**
-
- Excludes *launchSettings.json* from the generated template.
-
-- **`--no-https`**
-
- Turns off HTTPS. This option only applies if `Individual`, `IndividualB2C`, `SingleOrg`, or `MultiOrg` aren't being used for `--auth`.
-
-- **`-uld|--use-local-db`**
-
- Specifies LocalDB should be used instead of SQLite. Only applies to `Individual` or `IndividualB2C` authentication.
-
-- **`--no-restore`**
-
- Doesn't execute an implicit restore during project creation.
-
-- **`--kestrelHttpPort`**
-
- Port number to use for the HTTP endpoint in *launchSettings.json*.
-
-- **`--kestrelHttpsPort`**
-
- Port number to use for the HTTPS endpoint in *launchSettings.json*. This option is not applicable when the parameter `no-https` is used (but `no-https` is ignored when an individual or organizational authentication setting is chosen for `--auth`).
-
-- **`--use-program-main`**
-
- If specified, an explicit `Program` class and `Main` method will be used instead of top-level statements. Available since .NET SDK 6.0.300. Default value: `false`.
-
-***
-
-## `blazor`
+### `blazor`
- **`-f|--framework `**
@@ -448,19 +405,23 @@ The ability to create a project for an earlier TFM depends on having that versio
***
-## `blazorwasm`
+### `web`
+
+- **`--exclude-launch-settings`**
+
+ Excludes *launchSettings.json* from the generated template.
- **`-f|--framework `**
- Specifies the [framework](../../standard/frameworks.md) to target.
+ Specifies the [framework](../../standard/frameworks.md) to target. Option not available in .NET Core 2.2 SDK.
The following table lists the default values according to the SDK version number you're using:
- | SDK version | Default value |
- |-------------|-----------------|
- | 9.0 | `net9.0` |
- | 8.0 | `net8.0` |
- | 7.0 | `net7.0` |
+ | SDK version | Default value |
+ |-------------|---------------|
+ | 9.0 | `net9.0` |
+ | 8.0 | `net8.0` |
+ | 7.0 | `net7.0` |
To create a project that targets a framework earlier than the SDK that you're using, see [`--framework` for `console` projects](#template-options) earlier in this article.
@@ -468,9 +429,25 @@ The ability to create a project for an earlier TFM depends on having that versio
Doesn't execute an implicit restore during project creation.
-- **`-ho|--hosted`**
+- **`--no-https`**
- Includes an ASP.NET Core host for the Blazor WebAssembly app.
+ Turns off HTTPS.
+
+- **`--kestrelHttpPort`**
+
+ Port number to use for the HTTP endpoint in *launchSettings.json*.
+
+- **`--kestrelHttpsPort`**
+
+ Port number to use for the HTTPS endpoint in *launchSettings.json*. This option is not applicable when the parameter `no-https` is used (but `no-https` is ignored when an individual or organizational authentication setting is chosen for `--auth`).
+
+- **`--use-program-main`**
+
+ If specified, an explicit `Program` class and `Main` method will be used instead of top-level statements. Available since .NET SDK 6.0.300. Default value: `false`.
+
+***
+
+### `mvc`, `webapp`
- **`-au|--auth `**
@@ -480,78 +457,86 @@ The ability to create a project for an earlier TFM depends on having that versio
- `Individual` - Individual authentication.
- `IndividualB2C` - Individual authentication with Azure AD B2C.
- `SingleOrg` - Organizational authentication for a single tenant. Entra External ID tenants also use SingleOrg.
-
-- **`--authority `**
-
- The authority of the OIDC provider. Use with `Individual` authentication. The default value is `https://login.microsoftonline.com/`.
+ - `MultiOrg` - Organizational authentication for multiple tenants.
+ - `Windows` - Windows authentication.
- **`--aad-b2c-instance `**
- The Azure Active Directory B2C instance to connect to. Use with `IndividualB2C` authentication. The default value is `https://aadB2CInstance.b2clogin.com/`.
+ The Azure Active Directory B2C instance to connect to. Use with `IndividualB2C` authentication. The default value is `https://login.microsoftonline.com/tfp/`.
- **`-ssp|--susi-policy-id `**
The sign-in and sign-up policy ID for this project. Use with `IndividualB2C` authentication.
-- **`--aad-instance `**
-
- The Azure Active Directory instance to connect to. Use with `SingleOrg` authentication. The default value is `https://login.microsoftonline.com/`.
-
-- **`--client-id `**
+- **`-rp|--reset-password-policy-id `**
- The Client ID for this project. Use with `IndividualB2C`, `SingleOrg`, or `Individual` authentication in standalone scenarios. The default value is `33333333-3333-3333-33333333333333333`.
+ The reset password policy ID for this project. Use with `IndividualB2C` authentication.
-- **`--domain `**
+- **`-ep|--edit-profile-policy-id `**
- The domain for the directory tenant. Use with `SingleOrg` or `IndividualB2C` authentication. The default value is `qualified.domain.name`.
+ The edit profile policy ID for this project. Use with `IndividualB2C` authentication.
-- **`--app-id-uri `**
+- **`--aad-instance `**
- The App ID Uri for the server API you want to call. Use with `SingleOrg` or `IndividualB2C` authentication. The default value is `api.id.uri`.
+ The Azure Active Directory instance to connect to. Use with `SingleOrg` or `MultiOrg` authentication. The default value is `https://login.microsoftonline.com/`.
-- **`--api-client-id `**
+- **`--client-id `**
- The Client ID for the API that the server hosts. Use with `SingleOrg` or `IndividualB2C` authentication. The default value is `11111111-1111-1111-11111111111111111`.
+ The Client ID for this project. Use with `IndividualB2C`, `SingleOrg`, or `MultiOrg` authentication. The default value is `11111111-1111-1111-11111111111111111`.
-- **`-s|--default-scope `**
+- **`--domain `**
- The API scope the client needs to request to provision an access token. Use with `SingleOrg` or `IndividualB2C` authentication. The default value is `user_impersonation`.
+ The domain for the directory tenant. Use with `SingleOrg` or `IndividualB2C` authentication. The default value is `qualified.domain.name`.
- **`--tenant-id `**
The TenantId ID of the directory to connect to. Use with `SingleOrg` authentication. The default value is `22222222-2222-2222-2222-222222222222`.
+- **`--callback-path `**
+
+ The request path within the application's base path of the redirect URI. Use with `SingleOrg` or `IndividualB2C` authentication. The default value is `/signin-oidc`.
+
- **`-r|--org-read-access`**
- Allows this application read-access to the directory. Only applies to `SingleOrg` authentication.
+ Allows this application read-access to the directory. Only applies to `SingleOrg` or `MultiOrg` authentication.
- **`--exclude-launch-settings`**
Excludes *launchSettings.json* from the generated template.
-- **`-p|--pwa`**
-
- produces a Progressive Web Application (PWA) supporting installation and offline use.
-
- **`--no-https`**
- Turns off HTTPS. This option only applies if `Individual`, `IndividualB2C`, or `SingleOrg` aren't being used for `--auth`.
+ Turns off HTTPS. This option only applies if `Individual`, `IndividualB2C`, `SingleOrg`, or `MultiOrg` aren't being used.
- **`-uld|--use-local-db`**
Specifies LocalDB should be used instead of SQLite. Only applies to `Individual` or `IndividualB2C` authentication.
-- **`--called-api-url `**
+- **`-f|--framework `**
- URL of the API to call from the web app. Only applies to `SingleOrg` or `IndividualB2C` authentication without an ASP.NET Core host specified. The default value is `https://graph.microsoft.com/v1.0/me`.
+ Specifies the [framework](../../standard/frameworks.md) to target. Option available since .NET Core 3.0 SDK.
-- **`--calls-graph`**
+ The following table lists the default values according to the SDK version number you're using:
- Specifies if the web app calls Microsoft Graph. Only applies to `SingleOrg` authentication.
+ | SDK version | Default value |
+ |-------------|---------------|
+ | 9.0 | `net9.0` |
+ | 8.0 | `net8.0` |
+ | 7.0 | `net7.0` |
-- **`--called-api-scopes `**
+ To create a project that targets a framework earlier than the SDK that you're using, see [`--framework` for `console` projects](#template-options) earlier in this article.
- Scopes to request to call the API from the web app. Only applies to `SingleOrg` or `IndividualB2C` authentication without an ASP.NET Core host specified. The default is `user.read`.
+- **`--no-restore`**
+
+ Doesn't execute an implicit restore during project creation.
+
+- **`--use-browserlink`**
+
+ Includes BrowserLink in the project.
+
+- **`-rrc|--razor-runtime-compilation`**
+
+ Determines if the project is configured to use [Razor runtime compilation](/aspnet/core/mvc/views/view-compilation#runtime-compilation) in Debug builds.
- **`--kestrelHttpPort`**
@@ -567,41 +552,40 @@ The ability to create a project for an earlier TFM depends on having that versio
***
-## `web`
+### `razorclasslib`
-- **`--exclude-launch-settings`**
+- **`--no-restore`**
- Excludes *launchSettings.json* from the generated template.
+ Doesn't execute an implicit restore during project creation.
-- **`-f|--framework `**
+- **`-s|--support-pages-and-views`**
- Specifies the [framework](../../standard/frameworks.md) to target. Option not available in .NET Core 2.2 SDK.
+ Supports adding traditional Razor pages and Views in addition to components to this library.
- The following table lists the default values according to the SDK version number you're using:
+***
- | SDK version | Default value |
- |-------------|-----------------|
- | 9.0 | `net9.0` |
- | 8.0 | `net8.0` |
- | 7.0 | `net7.0` |
+### `webapiaot`
- To create a project that targets a framework earlier than the SDK that you're using, see [`--framework` for `console` projects](#template-options) earlier in this article.
+Creates a web API project with AOT publish enabled. For more information, see [Native AOT deployment](/dotnet/core/deploying/native-aot) and [The Web API (Native AOT) template](/aspnet/core/fundamentals/native-aot#the-web-api-native-aot-template).
-- **`--no-restore`**
+- **`--exclude-launch-settings`**
- Doesn't execute an implicit restore during project creation.
+ Excludes *launchSettings.json* from the generated template.
-- **`--no-https`**
+- **`-f|--framework `**
- Turns off HTTPS.
+ Specifies the [framework](../../standard/frameworks.md) to target.
-- **`--kestrelHttpPort`**
+ The following table lists the default values according to the SDK version number you're using:
- Port number to use for the HTTP endpoint in *launchSettings.json*.
+ | SDK version | Default value |
+ |-------------|---------------|
+ | 9.0 | `net9.0` |
+ | 8.0 | `net8.0` |
-- **`--kestrelHttpsPort`**
+- **`--no-restore`**
- Port number to use for the HTTPS endpoint in *launchSettings.json*. This option is not applicable when the parameter `no-https` is used (but `no-https` is ignored when an individual or organizational authentication setting is chosen for `--auth`).
+ Doesn't execute an implicit restore during project creation.
- **`--use-program-main`**
@@ -609,82 +593,80 @@ The ability to create a project for an earlier TFM depends on having that versio
***
-## `mvc`, `webapp`
+### `webapi`
- **`-au|--auth `**
The type of authentication to use. The possible values are:
- `None` - No authentication (Default).
- - `Individual` - Individual authentication.
- `IndividualB2C` - Individual authentication with Azure AD B2C.
- `SingleOrg` - Organizational authentication for a single tenant. Entra External ID tenants also use SingleOrg.
- - `MultiOrg` - Organizational authentication for multiple tenants.
- `Windows` - Windows authentication.
- **`--aad-b2c-instance `**
The Azure Active Directory B2C instance to connect to. Use with `IndividualB2C` authentication. The default value is `https://login.microsoftonline.com/tfp/`.
-- **`-ssp|--susi-policy-id `**
-
- The sign-in and sign-up policy ID for this project. Use with `IndividualB2C` authentication.
-
-- **`-rp|--reset-password-policy-id `**
+- **`-minimal|--use-minimal-apis`**
- The reset password policy ID for this project. Use with `IndividualB2C` authentication.
+ Create a project that uses the [ASP.NET Core minimal API](/aspnet/core/fundamentals/minimal-apis). Default is `false`, but this option is overridden by `-controllers`. Since the default for `-controllers` is `false`, entering `dotnet new webapi` without specifying either option creates a minimal API project.
-- **`-ep|--edit-profile-policy-id `**
+- **`-ssp|--susi-policy-id `**
- The edit profile policy ID for this project. Use with `IndividualB2C` authentication.
+ The sign-in and sign-up policy ID for this project. Use with `IndividualB2C` authentication.
- **`--aad-instance `**
- The Azure Active Directory instance to connect to. Use with `SingleOrg` or `MultiOrg` authentication. The default value is `https://login.microsoftonline.com/`.
+ The Azure Active Directory instance to connect to. Use with `SingleOrg` authentication. The default value is `https://login.microsoftonline.com/`.
- **`--client-id `**
- The Client ID for this project. Use with `IndividualB2C`, `SingleOrg`, or `MultiOrg` authentication. The default value is `11111111-1111-1111-11111111111111111`.
+ The Client ID for this project. Use with `IndividualB2C` or `SingleOrg` authentication. The default value is `11111111-1111-1111-11111111111111111`.
+
+- **`-controllers|--use-controllers`**
+
+ Whether to use controllers instead of minimal APIs. If both this option and `-minimal` are specified, this option overrides the value specified by `-minimal`. Default is `false`. Available since .NET 8 SDK.
- **`--domain `**
- The domain for the directory tenant. Use with `SingleOrg` or `IndividualB2C` authentication. The default value is `qualified.domain.name`.
+ The domain for the directory tenant. Use with `IndividualB2C` or `SingleOrg` authentication. The default value is `qualified.domain.name`.
- **`--tenant-id `**
The TenantId ID of the directory to connect to. Use with `SingleOrg` authentication. The default value is `22222222-2222-2222-2222-222222222222`.
-- **`--callback-path `**
-
- The request path within the application's base path of the redirect URI. Use with `SingleOrg` or `IndividualB2C` authentication. The default value is `/signin-oidc`.
-
- **`-r|--org-read-access`**
- Allows this application read-access to the directory. Only applies to `SingleOrg` or `MultiOrg` authentication.
+ Allows this application read-access to the directory. Only applies to `SingleOrg` authentication.
- **`--exclude-launch-settings`**
Excludes *launchSettings.json* from the generated template.
+- **`--no-openapi`**
+
+ Turns off OpenAPI (Swagger) support. `AddOpenApi` and `MapOpenApi` aren't called.
+
- **`--no-https`**
- Turns off HTTPS. This option only applies if `Individual`, `IndividualB2C`, `SingleOrg`, or `MultiOrg` aren't being used.
+ Turns off HTTPS. No *https* launch profile is created in `launchSettings.json`. `app.UseHsts` and `app.UseHttpsRedirection` aren't called in *Program.cs*/*Startup.cs*. This option only applies if `IndividualB2C` or `SingleOrg` aren't being used for authentication.
- **`-uld|--use-local-db`**
- Specifies LocalDB should be used instead of SQLite. Only applies to `Individual` or `IndividualB2C` authentication.
+ Specifies LocalDB should be used instead of SQLite. Only applies to `IndividualB2C` authentication.
- **`-f|--framework `**
- Specifies the [framework](../../standard/frameworks.md) to target. Option available since .NET Core 3.0 SDK.
+ Specifies the [framework](../../standard/frameworks.md) to target. Option not available in .NET Core 2.2 SDK.
The following table lists the default values according to the SDK version number you're using:
- | SDK version | Default value |
- |-------------|-----------------|
- | 9.0 | `net9.0` |
- | 8.0 | `net8.0` |
- | 7.0 | `net7.0` |
+ | SDK version | Default value |
+ |-------------|---------------|
+ | 9.0 | `net9.0` |
+ | 8.0 | `net8.0` |
+ | 7.0 | `net7.0` |
To create a project that targets a framework earlier than the SDK that you're using, see [`--framework` for `console` projects](#template-options) earlier in this article.
@@ -692,29 +674,67 @@ The ability to create a project for an earlier TFM depends on having that versio
Doesn't execute an implicit restore during project creation.
-- **`--use-browserlink`**
+- **`--use-program-main`**
- Includes BrowserLink in the project.
+ If specified, an explicit `Program` class and `Main` method will be used instead of top-level statements. Available since .NET SDK 6.0.300. Default value: `false`.
-- **`-rrc|--razor-runtime-compilation`**
+***
- Determines if the project is configured to use [Razor runtime compilation](/aspnet/core/mvc/views/view-compilation#runtime-compilation) in Debug builds.
+### `apicontroller`
-- **`--kestrelHttpPort`**
+API Controller with or without read/write actions.
- Port number to use for the HTTP endpoint in *launchSettings.json*.
+- **`-p:n|--name `**
-- **`--kestrelHttpsPort`**
+ The namespace for the generated code. Default is `MyApp.Namespace`.
- Port number to use for the HTTPS endpoint in *launchSettings.json*. This option is not applicable when the parameter `no-https` is used (but `no-https` is ignored when an individual or organizational authentication setting is chosen for `--auth`).
+- **`-ac|--actions`**
-- **`--use-program-main`**
+ Create a controller with read/write actions. Default is `false`.
- If specified, an explicit `Program` class and `Main` method will be used instead of top-level statements. Available since .NET SDK 6.0.300. Default value: `false`.
+***
+
+### `globaljson`
+
+- **`--sdk-version `**
+
+ Specifies the version of the .NET SDK to use in the *global.json* file.
+
+- **`--roll-forward `**
+
+ The roll-forward policy to use when selecting an SDK version, either as a fallback when a specific SDK version is missing or as a directive to use a later version.
+ For more information, see [global-json](global-json.md#rollforward).
+
+### `sln`
+
+Creates an empty solution file containing no projects.
+
+> [!NOTE]
+> In .NET SDK 9.0.200 and later, this template supports a `--format` option to choose between `sln` and `slnx` formats. Starting with .NET 10, the default format is `slnx`.
***
-## `angular`, `react`
+### `editorconfig`
+
+Creates an *.editorconfig* file for configuring code style preferences.
+
+- **`--empty`**
+
+ Creates an empty *.editorconfig* instead of the defaults for .NET.
+
+## Discontinued templates
+
+The following table shows templates that have been discontinued and no longer come preinstalled with the .NET SDK. To see any template-specific options, select the short name link.
+
+| Templates | Short name | Language | Tags | Discontinued since |
+|----------------------------|---------------------------------------|----------|-------------|--------------------|
+| ASP.NET Core with Angular | [`angular`](#spa) | [C#] | Web/MVC/SPA | 8.0 |
+| ASP.NET Core with React.js | [`react`](#spa) | [C#] | Web/MVC/SPA | 8.0 |
+| Blazor Server App | [`blazorserver`](#blazorserver) | [C#] | Web/Blazor | 8.0 |
+| Blazor Server App Empty | [`blazorserver-empty`](#blazorserver) | [C#] | Web/Blazor | 8.0 |
+| Blazor WebAssembly App Empty | [`blazorwasm-empty`](#blazorwasm) | [C#] | Web/Blazor/WebAssembly | 8.0 |
+
+### `angular`, `react`
**Discontinued since .NET 8 SDK.**
@@ -752,9 +772,9 @@ The ability to create a project for an earlier TFM depends on having that versio
> [!NOTE]
> There isn't a React template for `net8.0`, however, if you're interested in developing React apps with ASP.NET Core, see [Overview of Single Page Apps (SPAs) in ASP.NET Core](/aspnet/core/client-side/spa/intro?view=aspnetcore-8.0&preserve-view=true).
- | SDK version | Default value |
- |-------------|-----------------|
- | 7.0 | `net7.0` |
+ | SDK version | Default value |
+ |-------------|---------------|
+ | 7.0 | `net7.0` |
To create a project that targets a framework earlier than the SDK that you're using, see [`--framework` for `console` projects](#template-options) earlier in this article.
@@ -772,65 +792,131 @@ The ability to create a project for an earlier TFM depends on having that versio
***
-## `razorclasslib`
+### `blazorserver`
-- **`--no-restore`**
+**Discontinued since .NET 8 SDK.**
- Doesn't execute an implicit restore during project creation.
+- **`-au|--auth `**
-- **`-s|--support-pages-and-views`**
+ The type of authentication to use. The possible values are:
- Supports adding traditional Razor pages and Views in addition to components to this library.
+ - `None` - No authentication (Default).
+ - `Individual` - Individual authentication.
+ - `IndividualB2C` - Individual authentication with Azure AD B2C.
+ - `SingleOrg` - Organizational authentication for a single tenant. [Entra External ID](/entra/external-id/) tenants also use `SingleOrg`.
+ - `MultiOrg` - Organizational authentication for multiple tenants.
+ - `Windows` - Windows authentication.
-***
+- **`--aad-b2c-instance `**
-## `webapiaot`
+ The Azure Active Directory B2C instance to connect to. Use with `IndividualB2C` authentication. The default value is `https://login.microsoftonline.com/tfp/`.
-Creates a web API project with AOT publish enabled. For more information, see [Native AOT deployment](/dotnet/core/deploying/native-aot) and [The Web API (Native AOT) template](/aspnet/core/fundamentals/native-aot#the-web-api-native-aot-template).
+- **`-ssp|--susi-policy-id `**
+
+ The sign-in and sign-up policy ID for this project. Use with `IndividualB2C` authentication.
+
+- **`-rp|--reset-password-policy-id `**
+
+ The reset password policy ID for this project. Use with `IndividualB2C` authentication.
+
+- **`-ep|--edit-profile-policy-id `**
+
+ The edit profile policy ID for this project. Use with `IndividualB2C` authentication.
+
+- **`--aad-instance `**
+
+ The Azure Active Directory instance to connect to. Use with `SingleOrg` or `MultiOrg` authentication. The default value is `https://login.microsoftonline.com/`.
+
+- **`--client-id `**
+
+ The Client ID for this project. Use with `IndividualB2C`, `SingleOrg`, or `MultiOrg` authentication. The default value is `11111111-1111-1111-11111111111111111`.
+
+- **`--domain `**
+
+ The domain for the directory tenant. Use with `SingleOrg` or `IndividualB2C` authentication. The default value is `qualified.domain.name`.
+
+- **`--tenant-id `**
+
+ The TenantId ID of the directory to connect to. Use with `SingleOrg` authentication. The default value is `22222222-2222-2222-2222-222222222222`.
+
+- **`--callback-path `**
+
+ The request path within the application's base path of the redirect URI. Use with `SingleOrg` or `IndividualB2C` authentication. The default value is `/signin-oidc`.
+
+- **`-r|--org-read-access`**
+
+ Allows this application read-access to the directory. Only applies to `SingleOrg` or `MultiOrg` authentication.
- **`--exclude-launch-settings`**
Excludes *launchSettings.json* from the generated template.
-- **`-f|--framework `**
+- **`--no-https`**
- Specifies the [framework](../../standard/frameworks.md) to target.
+ Turns off HTTPS. This option only applies if `Individual`, `IndividualB2C`, `SingleOrg`, or `MultiOrg` aren't being used for `--auth`.
- The following table lists the default values according to the SDK version number you're using:
+- **`-uld|--use-local-db`**
- | SDK version | Default value |
- |-------------|-----------------|
- | 9.0 | `net9.0` |
- | 8.0 | `net8.0` |
+ Specifies LocalDB should be used instead of SQLite. Only applies to `Individual` or `IndividualB2C` authentication.
- **`--no-restore`**
Doesn't execute an implicit restore during project creation.
+- **`--kestrelHttpPort`**
+
+ Port number to use for the HTTP endpoint in *launchSettings.json*.
+
+- **`--kestrelHttpsPort`**
+
+ Port number to use for the HTTPS endpoint in *launchSettings.json*. This option is not applicable when the parameter `no-https` is used (but `no-https` is ignored when an individual or organizational authentication setting is chosen for `--auth`).
+
- **`--use-program-main`**
If specified, an explicit `Program` class and `Main` method will be used instead of top-level statements. Available since .NET SDK 6.0.300. Default value: `false`.
***
-## `webapi`
+### `blazorwasm`
+
+- **`-f|--framework `**
+
+ Specifies the [framework](../../standard/frameworks.md) to target.
+
+ The following table lists the default values according to the SDK version number you're using:
+
+ | SDK version | Default value |
+ |-------------|---------------|
+ | 9.0 | `net9.0` |
+ | 8.0 | `net8.0` |
+ | 7.0 | `net7.0` |
+
+ To create a project that targets a framework earlier than the SDK that you're using, see [`--framework` for `console` projects](#template-options) earlier in this article.
+
+- **`--no-restore`**
+
+ Doesn't execute an implicit restore during project creation.
+
+- **`-ho|--hosted`**
+
+ Includes an ASP.NET Core host for the Blazor WebAssembly app.
- **`-au|--auth `**
The type of authentication to use. The possible values are:
- `None` - No authentication (Default).
+ - `Individual` - Individual authentication.
- `IndividualB2C` - Individual authentication with Azure AD B2C.
- `SingleOrg` - Organizational authentication for a single tenant. Entra External ID tenants also use SingleOrg.
- - `Windows` - Windows authentication.
-- **`--aad-b2c-instance `**
+- **`--authority `**
- The Azure Active Directory B2C instance to connect to. Use with `IndividualB2C` authentication. The default value is `https://login.microsoftonline.com/tfp/`.
+ The authority of the OIDC provider. Use with `Individual` authentication. The default value is `https://login.microsoftonline.com/`.
-- **`-minimal|--use-minimal-apis`**
+- **`--aad-b2c-instance `**
- Create a project that uses the [ASP.NET Core minimal API](/aspnet/core/fundamentals/minimal-apis). Default is `false`, but this option is overridden by `-controllers`. Since the default for `-controllers` is `false`, entering `dotnet new webapi` without specifying either option creates a minimal API project.
+ The Azure Active Directory B2C instance to connect to. Use with `IndividualB2C` authentication. The default value is `https://aadB2CInstance.b2clogin.com/`.
- **`-ssp|--susi-policy-id `**
@@ -842,15 +928,23 @@ Creates a web API project with AOT publish enabled. For more information, see [N
- **`--client-id `**
- The Client ID for this project. Use with `IndividualB2C` or `SingleOrg` authentication. The default value is `11111111-1111-1111-11111111111111111`.
+ The Client ID for this project. Use with `IndividualB2C`, `SingleOrg`, or `Individual` authentication in standalone scenarios. The default value is `33333333-3333-3333-33333333333333333`.
-- **`-controllers|--use-controllers`**
+- **`--domain `**
- Whether to use controllers instead of minimal APIs. If both this option and `-minimal` are specified, this option overrides the value specified by `-minimal`. Default is `false`. Available since .NET 8 SDK.
+ The domain for the directory tenant. Use with `SingleOrg` or `IndividualB2C` authentication. The default value is `qualified.domain.name`.
-- **`--domain `**
+- **`--app-id-uri `**
- The domain for the directory tenant. Use with `IndividualB2C` or `SingleOrg` authentication. The default value is `qualified.domain.name`.
+ The App ID Uri for the server API you want to call. Use with `SingleOrg` or `IndividualB2C` authentication. The default value is `api.id.uri`.
+
+- **`--api-client-id `**
+
+ The Client ID for the API that the server hosts. Use with `SingleOrg` or `IndividualB2C` authentication. The default value is `11111111-1111-1111-11111111111111111`.
+
+- **`-s|--default-scope `**
+
+ The API scope the client needs to request to provision an access token. Use with `SingleOrg` or `IndividualB2C` authentication. The default value is `user_impersonation`.
- **`--tenant-id `**
@@ -864,84 +958,44 @@ Creates a web API project with AOT publish enabled. For more information, see [N
Excludes *launchSettings.json* from the generated template.
-- **`--no-openapi`**
+- **`-p|--pwa`**
- Turns off OpenAPI (Swagger) support. `AddOpenApi` and `MapOpenApi` aren't called.
+ produces a Progressive Web Application (PWA) supporting installation and offline use.
- **`--no-https`**
- Turns off HTTPS. No *https* launch profile is created in `launchSettings.json`. `app.UseHsts` and `app.UseHttpsRedirection` aren't called in *Program.cs*/*Startup.cs*. This option only applies if `IndividualB2C` or `SingleOrg` aren't being used for authentication.
+ Turns off HTTPS. This option only applies if `Individual`, `IndividualB2C`, or `SingleOrg` aren't being used for `--auth`.
- **`-uld|--use-local-db`**
- Specifies LocalDB should be used instead of SQLite. Only applies to `IndividualB2C` authentication.
-
-- **`-f|--framework `**
-
- Specifies the [framework](../../standard/frameworks.md) to target. Option not available in .NET Core 2.2 SDK.
-
- The following table lists the default values according to the SDK version number you're using:
-
- | SDK version | Default value |
- |-------------|-----------------|
- | 9.0 | `net9.0` |
- | 8.0 | `net8.0` |
- | 7.0 | `net7.0` |
-
- To create a project that targets a framework earlier than the SDK that you're using, see [`--framework` for `console` projects](#template-options) earlier in this article.
-
-- **`--no-restore`**
-
- Doesn't execute an implicit restore during project creation.
-
-- **`--use-program-main`**
-
- If specified, an explicit `Program` class and `Main` method will be used instead of top-level statements. Available since .NET SDK 6.0.300. Default value: `false`.
-
-***
-
-## `apicontroller`
-
-API Controller with or without read/write actions.
-
-- **`-p:n|--name `**
+ Specifies LocalDB should be used instead of SQLite. Only applies to `Individual` or `IndividualB2C` authentication.
- The namespace for the generated code. Default is `MyApp.Namespace`.
+- **`--called-api-url `**
-- **`-ac|--actions`**
+ URL of the API to call from the web app. Only applies to `SingleOrg` or `IndividualB2C` authentication without an ASP.NET Core host specified. The default value is `https://graph.microsoft.com/v1.0/me`.
- Create a controller with read/write actions. Default is `false`.
+- **`--calls-graph`**
-***
+ Specifies if the web app calls Microsoft Graph. Only applies to `SingleOrg` authentication.
-## `globaljson`
+- **`--called-api-scopes `**
-- **`--sdk-version `**
+ Scopes to request to call the API from the web app. Only applies to `SingleOrg` or `IndividualB2C` authentication without an ASP.NET Core host specified. The default is `user.read`.
- Specifies the version of the .NET SDK to use in the *global.json* file.
+- **`--kestrelHttpPort`**
-- **`--roll-forward `**
+ Port number to use for the HTTP endpoint in *launchSettings.json*.
- The roll-forward policy to use when selecting an SDK version, either as a fallback when a specific SDK version is missing or as a directive to use a later version.
- For more information, see [global-json](global-json.md#rollforward).
+- **`--kestrelHttpsPort`**
-## `sln`
+ Port number to use for the HTTPS endpoint in *launchSettings.json*. This option is not applicable when the parameter `no-https` is used (but `no-https` is ignored when an individual or organizational authentication setting is chosen for `--auth`).
-Creates an empty solution file containing no projects.
+- **`--use-program-main`**
-> [!NOTE]
-> In .NET SDK 9.0.200 and later, this template supports a `--format` option to choose between `sln` and `slnx` formats. Starting with .NET 10, the default format is `slnx`.
+ If specified, an explicit `Program` class and `Main` method will be used instead of top-level statements. Available since .NET SDK 6.0.300. Default value: `false`.
***
-## `editorconfig`
-
-Creates an *.editorconfig* file for configuring code style preferences.
-
-- **`--empty`**
-
- Creates an empty *.editorconfig* instead of the defaults for .NET.
-
## See also
- [dotnet new command](dotnet-new.md)
diff --git a/docs/core/tools/dotnet-new.md b/docs/core/tools/dotnet-new.md
index 205dd8a4ab574..dd3efffcf8d6c 100644
--- a/docs/core/tools/dotnet-new.md
+++ b/docs/core/tools/dotnet-new.md
@@ -56,7 +56,7 @@ To activate tab completion for the .NET SDK, see [Enable tab completion](enable-
Starting with .NET SDK 5.0.300, the [`search` command](dotnet-new-search.md) should be used to search for templates in NuGet.org.
-[!INCLUDE [templates](../../../includes/templates.md)]
+ For a list of templates that ship with the .NET SDK, see [Preinstalled templates](dotnet-new-sdk-templates.md#preinstalled-templates).
## Options
diff --git a/docs/csharp/language-reference/compiler-messages/cs8070.md b/docs/csharp/language-reference/compiler-messages/cs8070.md
new file mode 100644
index 0000000000000..a73f3b3cf4657
--- /dev/null
+++ b/docs/csharp/language-reference/compiler-messages/cs8070.md
@@ -0,0 +1,65 @@
+---
+description: "Compiler Error CS8070"
+title: "Compiler Error CS8070"
+ms.date: 9/05/2025
+f1_keywords:
+ - "CS8070"
+helpviewer_keywords:
+ - "CS8070"
+author: "StuartMosquera"
+---
+# Compiler Error CS8070
+
+Control cannot fall out of switch from final case label ('label')
+
+This error occurs when the last `case` or `default` case of a [switch statement](../statements/selection-statements.md#the-switch-statement) doesn't end with a jump statement such as:
+
+- [break](../statements/jump-statements.md#the-break-statement)
+- [return](../statements/jump-statements.md#the-return-statement)
+- [throw](../statements/exception-handling-statements.md#the-throw-statement)
+
+The following sample generates CS8070:
+
+```csharp
+// CS8070.cs
+public class MyClass
+{
+ public static void Main()
+ {
+ int i = 2;
+ int j = 0;
+
+ switch (i)
+ {
+ case 1:
+ i++;
+ break;
+
+ // Compiler error CS8070 is reported on the following line.
+ case 2:
+ i += 2;
+ // To resolve the error, uncomment one of the following example statements.
+ // break;
+ // return;
+ // throw new Exception("Fin");
+ }
+
+ switch (j)
+ {
+ case 1:
+ j++;
+ break;
+
+ case 2:
+ j += 2;
+ break;
+
+ // Compiler error CS8070 is reported on the following line.
+ default:
+ Console.WriteLine("Default");
+ // To resolve the error, uncomment the following line:
+ // break;
+ }
+ }
+}
+```
diff --git a/docs/csharp/language-reference/toc.yml b/docs/csharp/language-reference/toc.yml
index bfdabfaa0f964..4478184281dab 100644
--- a/docs/csharp/language-reference/toc.yml
+++ b/docs/csharp/language-reference/toc.yml
@@ -192,7 +192,7 @@ items:
- name: when (filter condition)
href: ./keywords/when.md
- name: field
- href: ./keywords/field.md
+ href: ./keywords/field.md
- name: value (implicit parameter)
href: ./keywords/value.md
- name: Query Keywords
@@ -382,8 +382,8 @@ items:
- name: Attributes read by the compiler
items:
- name: Global attributes
- displayName: >
- AssemblyName, AssemblyVersion, AssemblyCulture, AssemblyFlags, AssemblyProduct, AssemblyTrademark, AssemblyInformationalVersion,
+ displayName: >
+ AssemblyName, AssemblyVersion, AssemblyCulture, AssemblyFlags, AssemblyProduct, AssemblyTrademark, AssemblyInformationalVersion,
AssemblyCompany, AssemblyCopyright, AssemblyFileVersion, CLSCompliant, AssemblyTitle, AssemblyDescription, AssemblyConfiguration,
AssemblyDefaultAlias
href: ./attributes/global.md
@@ -396,7 +396,7 @@ items:
DoesNotReturn, DoesNotReturnIf
href: ./attributes/nullable-analysis.md
- name: Miscellaneous
- displayName: >
+ displayName: >
Conditional, Obsolete, Deprecated, Experimental, SetsRequiredMembers, AttributeUsage, AsyncMethodBuilder, InterpolatedStringHandler,
ModuleInitializer, SkipLocalsInit, UnscopedRef, OverloadResolutionPriority. EnumeratorCancellation, CollectionBuilder,
IUnknownConstant, IDispatchConstant, module initializer
@@ -407,7 +407,7 @@ items:
OptionalAttribute, OutAttribute, PreserveSigAttribute, SerializableAttribute, StructLayoutAttribute, IndexerNameAttribute,
DefaultParameterValueAttribute, InAttribute, SpecialNameAttribute, UnmanagedCallersOnlyAttribute, CompilerFeatureRequiredAttribute,
DecimalConstantAttribute, DefaultMemberAttribute, DynamicAttribute, ExtensionAttribute, FixedBufferAttribute, IsByRefLikeAttribute,
- IsReadOnlyAttribute, RequiresLocationAttribute, IsUnmanagedAttribute, NullableAttribute, NullableContextAttribute,
+ IsReadOnlyAttribute, RequiresLocationAttribute, IsUnmanagedAttribute, NullableAttribute, NullableContextAttribute,
NullablePublicOnlyAttribute, ParamArrayAttribute, ParamCollectionAttribute, RefSafetyRulesAttribute, RequiredMemberAttribute,
TupleElementNamesAttribute
href: ./attributes/pseudo-attributes.md
@@ -1878,6 +1878,8 @@ items:
href: ../misc/cs5001.md
- name: CS7003
href: ./compiler-messages/cs7003.md
+ - name: CS8070
+ href: ./compiler-messages/cs8070.md
- name: CS8124
href: ./compiler-messages/cs8124.md
- name: CS8125
diff --git a/docs/fundamentals/code-analysis/style-rules/language-rules.md b/docs/fundamentals/code-analysis/style-rules/language-rules.md
index 5aca6f4db12ca..bd86cd6744ebd 100644
--- a/docs/fundamentals/code-analysis/style-rules/language-rules.md
+++ b/docs/fundamentals/code-analysis/style-rules/language-rules.md
@@ -167,7 +167,7 @@ C# style rules:
- [Use collection expression for empty (IDE0301)](ide0301.md)
- [Use collection expression for stack alloc (IDE0302)](ide0302.md)
- [Use collection expression for `Create()` (IDE0303)](ide0303.md)
-- [Use collection expression for builder (IDE0304](ide0304.md)
+- [Use collection expression for builder (IDE0304)](ide0304.md)
- [Use collection expression for fluent (IDE0305)](ide0305.md)
- [Use collection expression for new (IDE0306)](ide0306.md)
- [Use unbound generic type (IDE0340)](ide0340.md)
diff --git a/docs/visual-basic/language-reference/operators/operator-precedence.md b/docs/visual-basic/language-reference/operators/operator-precedence.md
index ac2b2916e3a46..85f43d28a72b2 100644
--- a/docs/visual-basic/language-reference/operators/operator-precedence.md
+++ b/docs/visual-basic/language-reference/operators/operator-precedence.md
@@ -24,7 +24,7 @@ When several operations occur in an expression, each part is evaluated and resol
When expressions contain operators from more than one category, they are evaluated according to the following rules:
-- The arithmetic and concatenation operators have the order of precedence described in the following section, and all have greater precedence than the comparison, logical, and bitwise operators.
+- The arithmetic and concatenation operators have the order of precedence described in the following section, and all have greater precedence than the comparison, logical, and bitwise operators. Higher precedence means these operators are evaluated first.
- All comparison operators have equal precedence, and all have greater precedence than the logical and bitwise operators, but lower precedence than the arithmetic and concatenation operators.
@@ -34,13 +34,13 @@ When several operations occur in an expression, each part is evaluated and resol
## Precedence Order
- Operators are evaluated in the following order of precedence:
+ Operators are evaluated in the following order of precedence. Operators listed first have higher precedence and are evaluated before operators listed later:
-### Await Operator
+### 1. Await Operator
Await
-### Arithmetic and Concatenation Operators
+### 2. Arithmetic and Concatenation Operators
Exponentiation (`^`)
@@ -58,11 +58,11 @@ When several operations occur in an expression, each part is evaluated and resol
Arithmetic bit shift (`<<`, `>>`)
-### Comparison Operators
+### 3. Comparison Operators
All comparison operators (`=`, `<>`, `<`, `<=`, `>`, `>=`, `Is`, `IsNot`, `Like`, `TypeOf`...`Is`)
-### Logical and Bitwise Operators
+### 4. Logical and Bitwise Operators
Negation (`Not`)
@@ -108,7 +108,9 @@ e = 1.0
f = a - b + c / d * e
' The preceding line sets f to 7.0. Because of natural operator
' precedence and associativity, it is exactly equivalent to the
-' following line.
+' following line. Division and multiplication (/, *) have higher
+' precedence than addition and subtraction (+, -), so c / d * e
+' is evaluated first, then the addition and subtraction from left to right.
f = (a - b) + ((c / d) * e)
' The following line overrides the natural operator precedence
' and left associativity.
diff --git a/docs/visual-basic/language-reference/statements/with-end-with-statement.md b/docs/visual-basic/language-reference/statements/with-end-with-statement.md
index 2e1defd199c21..3e9f3a0908103 100644
--- a/docs/visual-basic/language-reference/statements/with-end-with-statement.md
+++ b/docs/visual-basic/language-reference/statements/with-end-with-statement.md
@@ -19,7 +19,7 @@ ms.assetid: 340d5fbb-4f43-48ec-a024-80843c137817
---
# With...End With Statement (Visual Basic)
-Executes a series of statements that repeatedly refer to a single object or structure so that the statements can use a simplified syntax when accessing members of the object or structure. When using a structure, you can only read the values of members or invoke methods, and you get an error if you try to assign values to members of a structure used in a `With...End With` statement.
+Executes a series of statements that repeatedly refer to a single object or structure so that the statements can use a simplified syntax when accessing members of the object or structure.
## Syntax
@@ -49,7 +49,7 @@ If your code accesses the same object in multiple statements, you gain the follo
- You make your code more readable by eliminating repetitive qualifying expressions.
-The data type of `objectExpression` can be any class or structure type or even a Visual Basic elementary type such as `Integer`. If `objectExpression` results in anything other than an object, you can only read the values of its members or invoke methods, and you get an error if you try to assign values to members of a structure used in a `With...End With` statement. This is the same error you would get if you invoked a method that returned a structure and immediately accessed and assigned a value to a member of the function’s result, such as `GetAPoint().x = 1`. The problem in both cases is that the structure exists only on the call stack, and there is no way a modified structure member in these situations can write to a location such that any other code in the program can observe the change.
+The data type of `objectExpression` can be any class or structure type or even a Visual Basic elementary type such as `Integer`. If `objectExpression` is a structure, the ability to assign to its members depends on whether the structure expression is referenceable. You can assign to members of structures that are directly referenceable (such as variables, array elements, or fields), but you get an error if you try to assign values to members of structures that are returned by value from functions, properties, or operators, or when parentheses are used to cut reference ties (for example, `With (structureVariable)`). This is the same error you would get if you invoked a method that returned a structure and immediately accessed and assigned a value to a member of the function's result, such as `GetAPoint().x = 1`. The problem in both cases is that the structure exists only on the call stack, and there is no way a modified structure member in these situations can write to a location such that any other code in the program can observe the change.
The `objectExpression` is evaluated once, upon entry into the block. You can't reassign the `objectExpression` from within the `With` block.
@@ -78,6 +78,12 @@ The following example nests `With…End With` statements. Within the nested `Wit
[!code-vb[VbVbalrWithStatement#1](~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbvbalrwithstatement/vb/mainwindow.xaml.vb#1)]
+## Example 3
+
+The following example demonstrates how `With...End With` statements work with structures. You can assign to members of referenceable structures (like array elements), but not to structures returned by value or when parentheses are used.
+
+[!code-vb[VbVbalrWithStatement#3](~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbvbalrwithstatement/vb/mainwindow.xaml.vb#3)]
+
## See also
-
diff --git a/docs/visual-basic/misc/bc30059.md b/docs/visual-basic/misc/bc30059.md
index ab6545d3190c1..e1cf71770bdc1 100644
--- a/docs/visual-basic/misc/bc30059.md
+++ b/docs/visual-basic/misc/bc30059.md
@@ -11,18 +11,97 @@ ms.assetid: fdd5e7bb-6370-4a63-bbb6-23b15badb4c8
---
# Constant expression is required
-A `Const` statement doesn't properly initialize a constant, or an array declaration uses a variable to specify the number of elements.
+A `Const` statement doesn't properly initialize a constant, an array declaration uses a variable to specify the number of elements, or you're trying to initialize an array as the default value for an optional parameter.
**Error ID:** BC30059
## To correct this error
-1. If the declaration is a `Const` statement, check to make sure the constant is initialized with a literal, a previously declared constant, an enumeration member, or a combination of literals, constants, and enumeration members combined with operators.
+- If the declaration is a `Const` statement, check to make sure the constant is initialized with a literal, a previously declared constant, an enumeration member, or a combination of literals, constants, and enumeration members combined with operators.
-2. If the declaration specifies an array, check to see if a variable is being used to specify the number of elements. If so, replace the variable with a constant expression.
+- If the declaration specifies an array, check to see if a variable is being used to specify the number of elements. If so, replace the variable with a constant expression.
+
+- If you're trying to initialize an array as the default value for an optional parameter, use one of the alternative approaches described in the [Array initialization in optional parameters](#array-initialization-in-optional-parameters) section.
-3. If the preceding checks don't address the issue, try setting the `Const` to a different temporary value, running the program, and then resetting the `Const` to the desired value.
+- If the preceding checks don't address the issue, try setting the `Const` to a different temporary value, running the program, and then resetting the `Const` to the desired value.
+
+## Array initialization in optional parameters
+
+You cannot initialize an array as the default value for an optional parameter because array initialization is not a constant expression. The following code generates BC30059:
+
+```vb
+' This causes BC30059
+Public Function MyFun(Optional filters() As (String, String) = New (String, String)() {}) As Boolean
+ ' Function body
+End Function
+```
+
+### Solution 1: Use ParamArray instead of Optional
+
+If you need to accept a variable number of arguments, consider using `ParamArray` instead of an optional parameter:
+
+```vb
+Public Function MyFun(ParamArray filters() As (String, String)) As Boolean
+ ' The ParamArray automatically provides an empty array if no arguments are passed
+ For Each filter In filters
+ ' Process each filter
+ Next
+ Return True
+End Function
+
+' Can be called with any number of arguments:
+MyFun() ' Empty array
+MyFun(("name", "value"))
+MyFun(("name1", "value1"), ("name2", "value2"))
+```
+
+### Solution 2: Use Nothing as default and initialize in the method body
+
+Set the default value to `Nothing` and check for it in your method:
+
+```vb
+Public Function MyFun(Optional filters() As (String, String) = Nothing) As Boolean
+ If filters Is Nothing Then
+ filters = New (String, String)() {}
+ End If
+
+ ' Process the filters array
+ For Each filter In filters
+ ' Process each filter
+ Next
+ Return True
+End Function
+
+' Can be called without arguments:
+MyFun() ' Uses empty array
+' Or with an array:
+MyFun({("name", "value")})
+```
+
+### Solution 3: Provide an overload without the parameter
+
+Create an overloaded version of the method that doesn't require the parameter:
+
+```vb
+' Overload without the parameter
+Public Function MyFun() As Boolean
+ Return MyFun(New (String, String)() {})
+End Function
+
+' Main method with required parameter
+Public Function MyFun(filters() As (String, String)) As Boolean
+ ' Process the filters array
+ For Each filter In filters
+ ' Process each filter
+ Next
+ Return True
+End Function
+```
## See also
- [Const Statement](../language-reference/statements/const-statement.md)
+- [Optional Parameters](../programming-guide/language-features/procedures/optional-parameters.md)
+- [Parameter Arrays](../programming-guide/language-features/procedures/parameter-arrays.md)
+- [How to: Initialize an Array Variable in Visual Basic](../programming-guide/language-features/arrays/how-to-initialize-an-array-variable.md)
+- [Arrays in Visual Basic](../programming-guide/language-features/arrays/index.md)
diff --git a/docs/visual-basic/programming-guide/concepts/async/index.md b/docs/visual-basic/programming-guide/concepts/async/index.md
index 446b743ed489d..c755fdd270e6d 100644
--- a/docs/visual-basic/programming-guide/concepts/async/index.md
+++ b/docs/visual-basic/programming-guide/concepts/async/index.md
@@ -1,254 +1,362 @@
---
description: "Learn more about: Asynchronous programming with Async and Await (Visual Basic)"
title: "Asynchronous Programming with Async and Await"
-ms.date: 07/20/2015
-ms.assetid: bd7e462b-583b-4395-9c36-45aa9e61072c
+ms.date: 08/29/2025
+ai-usage: ai-generated
---
# Asynchronous programming with Async and Await (Visual Basic)
-You can avoid performance bottlenecks and enhance the overall responsiveness of your application by using asynchronous programming. However, traditional techniques for writing asynchronous applications can be complicated, making them difficult to write, debug, and maintain.
+The [Task asynchronous programming (TAP) model](../../../../standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap.md) provides a layer of abstraction over typical asynchronous coding. In this model, you write code as a sequence of statements, the same as usual. The difference is you can read your task-based code as the compiler processes each statement and before it starts processing the next statement. To accomplish this model, the compiler performs many transformations to complete each task. Some statements can initiate work and return a object that represents the ongoing work and the compiler must resolve these transformations. The goal of task asynchronous programming is to enable code that reads like a sequence of statements, but executes in a more complicated order. Execution is based on external resource allocation and when tasks complete.
-Visual Studio 2012 introduced a simplified approach, async programming, that leverages asynchronous support in the .NET Framework 4.5 and higher as well as in the Windows Runtime. The compiler does the difficult work that the developer used to do, and your application retains a logical structure that resembles synchronous code. As a result, you get all the advantages of asynchronous programming with a fraction of the effort.
+The task asynchronous programming model is analogous to how people give instructions for processes that include asynchronous tasks. This article uses an example with instructions for making breakfast to show how the `Async` and `Await` keywords make it easier to reason about code that includes a series of asynchronous instructions. The instructions for making a breakfast might be provided as a list:
-This topic provides an overview of when and how to use async programming and includes links to support topics that contain details and examples.
+1. Pour a cup of coffee.
+2. Heat a pan, then fry two eggs.
+3. Cook three hash brown patties.
+4. Toast two pieces of bread.
+5. Spread butter and jam on the toast.
+6. Pour a glass of orange juice.
-## Async improves responsiveness
+If you have experience with cooking, you might complete these instructions **asynchronously**. You start warming the pan for eggs, then start cooking the hash browns. You put the bread in the toaster, then start cooking the eggs. At each step of the process, you start a task, and then transition to other tasks that are ready for your attention.
-Asynchrony is essential for activities that are potentially blocking, such as when your application accesses the web. Access to a web resource sometimes is slow or delayed. If such an activity is blocked within a synchronous process, the entire application must wait. In an asynchronous process, the application can continue with other work that doesn't depend on the web resource until the potentially blocking task finishes.
+Cooking breakfast is a good example of asynchronous work that isn't parallel. One person (or thread) can handle all the tasks. One person can make breakfast asynchronously by starting the next task before the previous task completes. Each cooking task progresses regardless of whether someone is actively watching the process. As soon as you start warming the pan for the eggs, you can begin cooking the hash browns. After the hash browns start to cook, you can put the bread in the toaster.
-The following table shows typical areas where asynchronous programming improves responsiveness. The listed APIs from the .NET Framework 4.5 and the Windows Runtime contain methods that support async programming.
+For a parallel algorithm, you need multiple people who cook (or multiple threads). One person cooks the eggs, another cooks the hash browns, and so on. Each person focuses on their one specific task. Each person who is cooking (or each thread) is blocked synchronously waiting for the current task to complete: Hash browns ready to flip, bread ready to pop up in toaster, and so on.
-|Application area|Supporting APIs that contain async methods|
-|----------------------|------------------------------------------------|
-|Web access|, |
-|Working with files|, , , |
-|Working with images|, , |
-|WCF programming|[Synchronous and Asynchronous Operations](../../../../framework/wcf/synchronous-and-asynchronous-operations.md)|
+:::image type="content" source="media/synchronous-breakfast.png" border="false" alt-text="Diagram that shows instructions for preparing breakfast as a list of seven sequential tasks completed in 30 minutes.":::
-Asynchrony proves especially valuable for applications that access the UI thread because all UI-related activity usually shares one thread. If any process is blocked in a synchronous application, all are blocked. Your application stops responding, and you might conclude that it has failed when instead it's just waiting.
+Consider the same list of synchronous instructions written as Visual Basic code statements:
-When you use asynchronous methods, the application continues to respond to the UI. You can resize or minimize a window, for example, or you can close the application if you don't want to wait for it to finish.
+:::code language="vb" source="snippets/breakfast/Program.vb" id="SynchronousBreakfast":::
-The async-based approach adds the equivalent of an automatic transmission to the list of options that you can choose from when designing asynchronous operations. That is, you get all the benefits of traditional asynchronous programming but with much less effort from the developer.
+If you interpret these instructions as a computer would, breakfast takes about 30 minutes to prepare. The duration is the sum of the individual task times. The computer blocks for each statement until all work completes, and then it proceeds to the next task statement. This approach can take significant time. In the breakfast example, the computer method creates an unsatisfying breakfast. Later tasks in the synchronous list, like toasting the bread, don't start until earlier tasks complete. Some food gets cold before the breakfast is ready to serve.
-## Async methods are easier to write
+If you want the computer to execute instructions asynchronously, you must write asynchronous code. When you write client programs, you want the UI to be responsive to user input. Your application shouldn't freeze all interaction while downloading data from the web. When you write server programs, you don't want to block threads that might be serving other requests. Using synchronous code when asynchronous alternatives exist hurts your ability to scale out less expensively. You pay for blocked threads.
-The [Async](../../../language-reference/modifiers/async.md) and [Await](../../../language-reference/operators/await-operator.md) keywords in Visual Basic are the heart of async programming. By using those two keywords, you can use resources in the .NET Framework or the Windows Runtime to create an asynchronous method almost as easily as you create a synchronous method. Asynchronous methods that you define by using `Async` and `Await` are referred to as async methods.
+Successful modern apps require asynchronous code. Without language support, writing asynchronous code requires callbacks, completion events, or other means that obscure the original intent of the code. The advantage of synchronous code is the step-by-step action that makes it easy to scan and understand. Traditional asynchronous models force you to focus on the asynchronous nature of the code, not on the fundamental actions of the code.
-The following example shows an async method. Almost everything in the code should look completely familiar to you. The comments call out the features that you add to create the asynchrony.
+## Don't block, await instead
-You can find a complete Windows Presentation Foundation (WPF) example file at the end of this topic, and you can download the sample from [Async Sample: Example from "Asynchronous Programming with Async and Await"](/samples/dotnet/samples/async-and-await-vb/).
+The previous code highlights an unfortunate programming practice: Writing synchronous code to perform asynchronous operations. The code blocks the current thread from doing any other work. The code doesn't interrupt the thread while there are running tasks. The outcome of this model is similar to staring at the toaster after you put in the bread. You ignore any interruptions and don't start other tasks until the bread pops up. You don't take the butter and jam out of the fridge. You might miss seeing a fire starting on the stove. You want to both toast the bread and handle other concerns at the same time. The same is true with your code.
-```vb
-' Three things to note about writing an Async Function:
-' - The function has an Async modifier.
-' - Its return type is Task or Task(Of T). (See "Return Types" section.)
-' - As a matter of convention, its name ends in "Async".
-Async Function AccessTheWebAsync() As Task(Of Integer)
- Using client As New HttpClient()
- ' Call and await separately.
- ' - AccessTheWebAsync can do other things while GetStringAsync is also running.
- ' - getStringTask stores the task we get from the call to GetStringAsync.
- ' - Task(Of String) means it is a task which returns a String when it is done.
- Dim getStringTask As Task(Of String) =
- client.GetStringAsync("https://learn.microsoft.com/dotnet")
- ' You can do other work here that doesn't rely on the string from GetStringAsync.
- DoIndependentWork()
- ' The Await operator suspends AccessTheWebAsync.
- ' - AccessTheWebAsync does not continue until getStringTask is complete.
- ' - Meanwhile, control returns to the caller of AccessTheWebAsync.
- ' - Control resumes here when getStringTask is complete.
- ' - The Await operator then retrieves the String result from getStringTask.
- Dim urlContents As String = Await getStringTask
- ' The Return statement specifies an Integer result.
- ' A method which awaits AccessTheWebAsync receives the Length value.
- Return urlContents.Length
-
- End Using
+You can start by updating the code so the thread doesn't block while tasks are running. The `Await` keyword provides a nonblocking way to start a task, then continue execution when the task completes. A simple asynchronous version of the breakfast code looks like the following snippet:
-End Function
-```
+:::code language="vb" source="snippets/breakfast/AsyncBreakfast.vb" id="AsyncBreakfast":::
-If `AccessTheWebAsync` doesn't have any work that it can do between calling `GetStringAsync` and awaiting its completion, you can simplify your code by calling and awaiting in the following single statement.
+The code updates the original method bodies of `FryEggs`, `FryHashBrowns`, and `ToastBread` to return `Task(Of Egg)`, `Task(Of HashBrown)`, and `Task(Of Toast)` objects, respectively. The updated method names include the "Async" suffix: `FryEggsAsync`, `FryHashBrownsAsync`, and `ToastBreadAsync`. The `Main` function returns the `Task` object, although it doesn't have a `Return` expression, which is by design.
-```vb
-Dim urlContents As String = Await client.GetStringAsync()
-```
+> [!NOTE]
+> The updated code doesn't yet take advantage of key features of asynchronous programming, which can result in shorter completion times. The code processes the tasks in roughly the same amount of time as the initial synchronous version. For the full method implementations, see the final version of the code later in this article.
-The following characteristics summarize what makes the previous example an async method:
+Let's apply the breakfast example to the updated code. The thread doesn't block while the eggs or hash browns are cooking, but the code also doesn't start other tasks until the current work completes. You still put the bread in the toaster and stare at the toaster until the bread pops up, but you can now respond to interruptions. In a restaurant where multiple orders are placed, the cook can start a new order while another is already cooking.
-- The method signature includes an `Async` modifier.
-- The name of an async method, by convention, ends with an "Async" suffix.
-- The return type is one of the following types:
+In the updated code, the thread working on the breakfast isn't blocked while waiting for any started task that's unfinished. For some applications, this change is all you need. You can enable your app to support user interaction while data downloads from the web. In other scenarios, you might want to start other tasks while waiting for the previous task to complete.
- - [Task(Of TResult)](xref:System.Threading.Tasks.Task%601) if your method has a return statement in which the operand has type TResult.
- - if your method has no return statement or has a return statement with no operand.
- - [Sub](../../language-features/procedures/sub-procedures.md) if you're writing an async event handler.
+## Start tasks concurrently
- For more information, see "Return Types and Parameters" later in this topic.
+For most operations, you want to start several independent tasks immediately. As each task completes, you initiate other work that's ready to start. When you apply this methodology to the breakfast example, you can prepare breakfast more quickly. You also get everything ready close to the same time, so you can enjoy a hot breakfast.
-- The method usually includes at least one await expression, which marks a point where the method can't continue until the awaited asynchronous operation is complete. In the meantime, the method is suspended, and control returns to the method's caller. The next section of this topic illustrates what happens at the suspension point.
+The class and related types are classes you can use to apply this style of reasoning to tasks that are in progress. This approach enables you to write code that more closely resembles the way you create breakfast in real life. You start cooking the eggs, hash browns, and toast at the same time. As each food item requires action, you turn your attention to that task, take care of the action, and then wait for something else that requires your attention.
-In async methods, you use the provided keywords and types to indicate what you want to do, and the compiler does the rest, including keeping track of what must happen when control returns to an await point in a suspended method. Some routine processes, such as loops and exception handling, can be difficult to handle in traditional asynchronous code. In an async method, you write these elements much as you would in a synchronous solution, and the problem is solved.
+In your code, you start a task and hold on to the object that represents the work. You use the `Await` method on the task to delay acting on the work until the result is ready.
-For more information about asynchrony in previous versions of the .NET Framework, see [TPL and Traditional .NET Framework Asynchronous Programming](../../../../standard/parallel-programming/tpl-and-traditional-async-programming.md).
+Apply these changes to the breakfast code. The first step is to store the tasks for operations when they start, rather than using the `Await` expression:
-## What happens in an Async method
-
-The most important thing to understand in asynchronous programming is how the control flow moves from method to method. The following diagram leads you through the process:
+```vb
+Dim cup As Coffee = PourCoffee()
+Console.WriteLine("Coffee is ready")
+
+Dim eggsTask As Task(Of Egg) = FryEggsAsync(2)
+Dim eggs As Egg = Await eggsTask
+Console.WriteLine("Eggs are ready")
+
+Dim hashBrownTask As Task(Of HashBrown) = FryHashBrownsAsync(3)
+Dim hashBrown As HashBrown = Await hashBrownTask
+Console.WriteLine("Hash browns are ready")
+
+Dim toastTask As Task(Of Toast) = ToastBreadAsync(2)
+Dim toast As Toast = Await toastTask
+ApplyButter(toast)
+ApplyJam(toast)
+Console.WriteLine("Toast is ready")
+
+Dim oj As Juice = PourOJ()
+Console.WriteLine("Oj is ready")
+Console.WriteLine("Breakfast is ready!")
+```
-
+These revisions don't help to get your breakfast ready any faster. The `Await` expression is applied to all tasks as soon as they start. The next step is to move the `Await` expressions for the hash browns and eggs to the end of the method, before you serve the breakfast:
-The numbers in the diagram correspond to the following steps:
+```vb
+Dim cup As Coffee = PourCoffee()
+Console.WriteLine("Coffee is ready")
+
+Dim eggsTask As Task(Of Egg) = FryEggsAsync(2)
+Dim hashBrownTask As Task(Of HashBrown) = FryHashBrownsAsync(3)
+Dim toastTask As Task(Of Toast) = ToastBreadAsync(2)
+
+Dim toast As Toast = Await toastTask
+ApplyButter(toast)
+ApplyJam(toast)
+Console.WriteLine("Toast is ready")
+Dim oj As Juice = PourOJ()
+Console.WriteLine("Oj is ready")
+
+Dim eggs As Egg = Await eggsTask
+Console.WriteLine("Eggs are ready")
+Dim hashBrown As HashBrown = Await hashBrownTask
+Console.WriteLine("Hash browns are ready")
+
+Console.WriteLine("Breakfast is ready!")
+```
-1. An event handler calls and awaits the `AccessTheWebAsync` async method.
+You now have an asynchronously prepared breakfast that takes about 20 minutes to prepare. The total cook time is reduced because some tasks run concurrently.
-2. `AccessTheWebAsync` creates an instance and calls the asynchronous method to download the contents of a website as a string.
+:::image type="content" source="media/asynchronous-breakfast.png" border="false" alt-text="Diagram that shows instructions for preparing breakfast as eight asynchronous tasks that complete in about 20 minutes, where unfortunately, the eggs and hash browns burn.":::
-3. Something happens in `GetStringAsync` that suspends its progress. Perhaps it must wait for a website to download or some other blocking activity. To avoid blocking resources, `GetStringAsync` yields control to its caller, `AccessTheWebAsync`.
+The code updates improve the preparation process by reducing the cook time, but they introduce a regression by burning the eggs and hash browns. You start all the asynchronous tasks at once. You wait on each task only when you need the results. The code might be similar to program in a web application that makes requests to different microservices and then combines the results into a single page. You make all the requests immediately, and then apply the `Await` expression on all those tasks and compose the web page.
- `GetStringAsync` returns a [Task(Of TResult)](xref:System.Threading.Tasks.Task%601) where TResult is a string, and `AccessTheWebAsync` assigns the task to the `getStringTask` variable. The task represents the ongoing process for the call to `GetStringAsync`, with a commitment to produce an actual string value when the work is complete.
+## Support composition with tasks
-4. Because `getStringTask` hasn't been awaited yet, `AccessTheWebAsync` can continue with other work that doesn't depend on the final result from `GetStringAsync`. That work is represented by a call to the synchronous method `DoIndependentWork`.
+The previous code revisions help get everything ready for breakfast at the same time, except the toast. The process of making the toast is a *composition* of an asynchronous operation (toast the bread) with synchronous operations (spread butter and jam on the toast). This example illustrates an important concept about asynchronous programming:
-5. `DoIndependentWork` is a synchronous method that does its work and returns to its caller.
+> [!IMPORTANT]
+> The composition of an asynchronous operation followed by synchronous work is an asynchronous operation. Stated another way, if any portion of an operation is asynchronous, the entire operation is asynchronous.
-6. `AccessTheWebAsync` has run out of work that it can do without a result from `getStringTask`. `AccessTheWebAsync` next wants to calculate and return the length of the downloaded string, but the method can't calculate that value until the method has the string.
+In the previous updates, you learned how to use or objects to hold running tasks. You wait on each task before you use its result. The next step is to create methods that represent the combination of other work. Before you serve breakfast, you want to wait on the task that represents toasting the bread before you spread the butter and jam.
- Therefore, `AccessTheWebAsync` uses an await operator to suspend its progress and to yield control to the method that called `AccessTheWebAsync`. `AccessTheWebAsync` returns a `Task(Of Integer)` to the caller. The task represents a promise to produce an integer result that's the length of the downloaded string.
+You can represent this work with the following code:
- > [!NOTE]
- > If `GetStringAsync` (and therefore `getStringTask`) is complete before `AccessTheWebAsync` awaits it, control remains in `AccessTheWebAsync`. The expense of suspending and then returning to `AccessTheWebAsync` would be wasted if the called asynchronous process (`getStringTask`) has already completed and AccessTheWebSync doesn't have to wait for the final result.
+```vb
+Async Function MakeToastWithButterAndJamAsync(number As Integer) As Task(Of Toast)
+ Dim toast As Toast = Await ToastBreadAsync(number)
+ ApplyButter(toast)
+ ApplyJam(toast)
- Inside the caller (the event handler in this example), the processing pattern continues. The caller might do other work that doesn't depend on the result from `AccessTheWebAsync` before awaiting that result, or the caller might await immediately. The event handler is waiting for `AccessTheWebAsync`, and `AccessTheWebAsync` is waiting for `GetStringAsync`.
+ Return toast
+End Function
+```
-7. `GetStringAsync` completes and produces a string result. The string result isn't returned by the call to `GetStringAsync` in the way that you might expect. (Remember that the method already returned a task in step 3.) Instead, the string result is stored in the task that represents the completion of the method, `getStringTask`. The await operator retrieves the result from `getStringTask`. The assignment statement assigns the retrieved result to `urlContents`.
+The `MakeToastWithButterAndJamAsync` method has the `Async` modifier in its signature that signals to the compiler that the method contains an `Await` expression and contains asynchronous operations. The method represents the task that toasts the bread, then spreads the butter and jam. The method returns a object that represents the composition of the three operations.
-8. When `AccessTheWebAsync` has the string result, the method can calculate the length of the string. Then the work of `AccessTheWebAsync` is also complete, and the waiting event handler can resume. In the full example at the end of the topic, you can confirm that the event handler retrieves and prints the value of the length result.
+The revised main block of code now looks like this:
-If you are new to asynchronous programming, take a minute to consider the difference between synchronous and asynchronous behavior. A synchronous method returns when its work is complete (step 5), but an async method returns a task value when its work is suspended (steps 3 and 6). When the async method eventually completes its work, the task is marked as completed and the result, if any, is stored in the task.
+```vb
+Async Function Main() As Task
+ Dim cup As Coffee = PourCoffee()
+ Console.WriteLine("coffee is ready")
-For more information about control flow, see [Control Flow in Async Programs (Visual Basic)](control-flow-in-async-programs.md).
+ Dim eggsTask = FryEggsAsync(2)
+ Dim hashBrownTask = FryHashBrownsAsync(3)
+ Dim toastTask = MakeToastWithButterAndJamAsync(2)
-## API Async Methods
+ Dim eggs = Await eggsTask
+ Console.WriteLine("eggs are ready")
-You might be wondering where to find methods such as `GetStringAsync` that support async programming. The .NET Framework 4.5 or higher contains many members that work with `Async` and `Await`. You can recognize these members by the "Async" suffix that's attached to the member name and a return type of or [Task(Of TResult)](xref:System.Threading.Tasks.Task%601). For example, the `System.IO.Stream` class contains methods such as , , and alongside the synchronous methods , , and .
+ Dim hashBrown = Await hashBrownTask
+ Console.WriteLine("hash browns are ready")
-The Windows Runtime also contains many methods that you can use with `Async` and `Await` in Windows apps. For more information and example methods, see [Call asynchronous APIs in C# or Visual Basic](/windows/uwp/threading-async/call-asynchronous-apis-in-csharp-or-visual-basic), [Asynchronous programming (Windows Runtime apps)](/previous-versions/windows/apps/hh464924(v=win.10)), and [WhenAny: Bridging between the .NET Framework and the Windows Runtime](/previous-versions/visualstudio/visual-studio-2013/jj635140(v=vs.120)).
+ Dim toast = Await toastTask
+ Console.WriteLine("toast is ready")
-## Threads
+ Dim oj As Juice = PourOJ()
+ Console.WriteLine("oj is ready")
+ Console.WriteLine("Breakfast is ready!")
+End Function
+```
-Async methods are intended to be non-blocking operations. An `Await` expression in an async method doesn't block the current thread while the awaited task is running. Instead, the expression signs up the rest of the method as a continuation and returns control to the caller of the async method.
+This code change illustrates an important technique for working with asynchronous code. You compose tasks by separating the operations into a new method that returns a task. You can choose when to wait on that task. You can start other tasks concurrently.
-The `Async` and `Await` keywords don't cause additional threads to be created. Async methods don't require multi-threading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active. You can use to move CPU-bound work to a background thread, but a background thread doesn't help with a process that's just waiting for results to become available.
+## Handle asynchronous exceptions
-The async-based approach to asynchronous programming is preferable to existing approaches in almost every case. In particular, this approach is better than for I/O-bound operations because the code is simpler and you don't have to guard against race conditions. In combination with , async programming is better than for CPU-bound operations because async programming separates the coordination details of running your code from the work that `Task.Run` transfers to the threadpool.
+Up to this point, your code implicitly assumes all tasks complete successfully. Asynchronous methods throw exceptions, just like their synchronous counterparts. The goals for asynchronous support for exceptions and error handling are the same as for asynchronous support in general. The best practice is to write code that reads like a series of synchronous statements. Tasks throw exceptions when they can't complete successfully. The client code can catch those exceptions when the `Await` expression is applied to a started task.
-## Async and Await
+In the breakfast example, suppose the toaster catches fire while toasting the bread. You can simulate that problem by modifying the `ToastBreadAsync` method to match the following code:
-If you specify that a method is an async method by using an [Async](../../../language-reference/modifiers/async.md) modifier, you enable the following two capabilities.
+```vb
+Private Async Function ToastBreadAsync(slices As Integer) As Task(Of Toast)
+ For slice As Integer = 0 To slices - 1
+ Console.WriteLine("Putting a slice of bread in the toaster")
+ Next
+ Console.WriteLine("Start toasting...")
+ Await Task.Delay(2000)
+ Console.WriteLine("Fire! Toast is ruined!")
+ Throw New InvalidOperationException("The toaster is on fire")
+ Await Task.Delay(1000)
+ Console.WriteLine("Remove toast from toaster")
+
+ Return New Toast()
+End Function
+```
-- The marked async method can use [Await](../../../language-reference/operators/await-operator.md) to designate suspension points. The await operator tells the compiler that the async method can't continue past that point until the awaited asynchronous process is complete. In the meantime, control returns to the caller of the async method.
+> [!NOTE]
+> When you compile this code, you see a warning about unreachable code. This error is by design. After the toaster catches fire, operations don't proceed normally and the code returns an error.
+
+After you make the code changes, run the application and check the output:
+
+```console
+Pouring coffee
+Coffee is ready
+Warming the egg pan...
+putting 3 hash brown patties in the pan
+Cooking first side of hash browns...
+Putting a slice of bread in the toaster
+Putting a slice of bread in the toaster
+Start toasting...
+Fire! Toast is ruined!
+Flipping a hash brown patty
+Flipping a hash brown patty
+Flipping a hash brown patty
+Cooking the second side of hash browns...
+Cracking 2 eggs
+Cooking the eggs ...
+Put hash browns on plate
+Put eggs on plate
+Eggs are ready
+Hash browns are ready
+Unhandled exception. System.InvalidOperationException: The toaster is on fire
+ at AsyncBreakfast.Program.ToastBreadAsync(Int32 slices) in Program.vb:line 65
+ at AsyncBreakfast.Program.MakeToastWithButterAndJamAsync(Int32 number) in Program.vb:line 36
+ at AsyncBreakfast.Program.Main(String[] args) in Program.vb:line 24
+ at AsyncBreakfast.Program.(String[] args)
+```
- The suspension of an async method at an `Await` expression doesn't constitute an exit from the method, and `Finally` blocks don't run.
+Notice that quite a few tasks finish between the time when the toaster catches fire and the system observes the exception. When a task that runs asynchronously throws an exception, that task is **faulted**. The object holds the exception that was thrown in the property. Faulted tasks *throw* the exception when the `Await` expression is applied to the task.
-- The marked async method can itself be awaited by methods that call it.
+There are two important mechanisms to understand about this process:
-An async method typically contains one or more occurrences of an `Await` operator, but the absence of `Await` expressions doesn't cause a compiler error. If an async method doesn't use an `Await` operator to mark a suspension point, the method executes as a synchronous method does, despite the `Async` modifier. The compiler issues a warning for such methods.
+- How an exception is stored in a faulted task.
+- How an exception is unpackaged and rethrown when code waits (`Await`) on a faulted task.
-`Async` and `Await` are contextual keywords. For more information and examples, see the following topics:
+When code running asynchronously throws an exception, the exception is stored in the object. The property is an object because more than one exception might be thrown during asynchronous work. Any exception thrown is added to the collection. If the `Exception` property is null, a new `AggregateException` object is created and the thrown exception is the first item in the collection.
-- [Async](../../../language-reference/modifiers/async.md)
-- [Await Operator](../../../language-reference/operators/await-operator.md)
+The most common scenario for a faulted task is that the `Exception` property contains exactly one exception. When your code waits on a faulted task, it rethrows the first exception in the collection. This result is the reason why the output from the example shows an object rather than an `AggregateException` object. Extracting the first inner exception makes working with asynchronous methods as similar as possible to working with their synchronous counterparts. You can examine the `Exception` property in your code when your scenario might generate multiple exceptions.
-## Return types and parameters
+> [!TIP]
+> The recommended practice is for any argument validation exceptions to emerge *synchronously* from task-returning methods. For more information and examples, see [Exceptions in task-returning methods](../../../../standard/exceptions/best-practices-for-exceptions.md#catch-cancellation-and-asynchronous-exceptions).
-In .NET Framework programming, an async method typically returns a or a [Task(Of TResult)](xref:System.Threading.Tasks.Task%601). Inside an async method, an `Await` operator is applied to a task that's returned from a call to another async method.
+Before you continue to the next section, comment out the following two statements in your `ToastBreadAsync` method. You don't want to start another fire:
-You specify [Task(Of TResult)](xref:System.Threading.Tasks.Task%601) as the return type if the method contains a [Return](../../../language-reference/statements/return-statement.md) statement that specifies an operand of type `TResult`.
+```vb
+' Console.WriteLine("Fire! Toast is ruined!")
+' Throw New InvalidOperationException("The toaster is on fire")
+```
-You use `Task` as the return type if the method has no return statement or has a return statement that doesn't return an operand.
+## Apply await expressions to tasks efficiently
-The following example shows how you declare and call a method that returns a [Task(Of TResult)](xref:System.Threading.Tasks.Task%601) or a :
+You can improve the series of `Await` expressions at the end of the previous code by using methods of the class. One API is the method, which returns a object that completes when all the tasks in its argument list are complete. The following code demonstrates this method:
```vb
-' Signature specifies Task(Of Integer)
-Async Function TaskOfTResult_MethodAsync() As Task(Of Integer)
+Await Task.WhenAll(eggsTask, hashBrownTask, toastTask)
+Console.WriteLine("Eggs are ready")
+Console.WriteLine("Hash browns are ready")
+Console.WriteLine("Toast is ready")
+Console.WriteLine("Breakfast is ready!")
+```
- Dim hours As Integer
- ' . . .
- ' Return statement specifies an integer result.
- Return hours
-End Function
+Another option is to use the method, which returns a `Task(Of Task)` object that completes when any of its arguments complete. You can wait on the returned task because you know the task is done. The following code shows how you can use the method to wait on the first task to finish and then process its result. After you process the result from the completed task, you remove the completed task from the list of tasks passed to the `WhenAny` method.
-' Calls to TaskOfTResult_MethodAsync
-Dim returnedTaskTResult As Task(Of Integer) = TaskOfTResult_MethodAsync()
-Dim intResult As Integer = Await returnedTaskTResult
-' or, in a single statement
-Dim intResult As Integer = Await TaskOfTResult_MethodAsync()
+:::code language="vb" source="snippets/breakfast/ConcurrentBreakfast.vb" id="ConcurrentBreakfast":::
-' Signature specifies Task
-Async Function Task_MethodAsync() As Task
+Near the end of the code snippet, notice the `Await finishedTask` expression. This line is important because `Task.WhenAny` returns a `Task(Of Task)` - a wrapper task that contains the completed task. When you `Await Task.WhenAny`, you're waiting for the wrapper task to complete, and the result is the actual task that finished first. However, to retrieve that task's result or ensure any exceptions are properly thrown, you must `Await` the completed task itself (stored in `finishedTask`). Even though you know the task has finished, awaiting it again allows you to access its result or handle any exceptions that might have caused it to fault.
- ' . . .
- ' The method has no return statement.
-End Function
+### Review final code
-' Calls to Task_MethodAsync
-Task returnedTask = Task_MethodAsync()
-Await returnedTask
-' or, in a single statement
-Await Task_MethodAsync()
-```
+Here's what the final version of the code looks like:
+
+:::code language="vb" source="snippets/breakfast/ConcurrentBreakfast.vb" id="ConcurrentBreakfast":::
-Each returned task represents ongoing work. A task encapsulates information about the state of the asynchronous process and, eventually, either the final result from the process or the exception that the process raises if it doesn't succeed.
+:::image type="content" source="media/whenany-async-breakfast.png" border="false" alt-text="Diagram that shows instructions for preparing breakfast as six asynchronous tasks that complete in about 15 minutes, and the code monitors for possible interruptions.":::
-An async method can also be a `Sub` method. This return type is used primarily to define event handlers, where a return type is required. Async event handlers often serve as the starting point for async programs.
+The code completes the asynchronous breakfast tasks in about 15 minutes. The total time is reduced because some tasks run concurrently. The code simultaneously monitors multiple tasks and takes action only as needed.
-An async method that's a `Sub` procedure can't be awaited, and the caller can't catch any exceptions that the method throws.
+The final code is asynchronous. It more accurately reflects how a person might cook breakfast. Compare the final code with the first code sample in the article. The core actions are still clear by reading the code. You can read the final code the same way you read the list of instructions for making a breakfast, as shown at the beginning of the article. The language features for the `Async` and `Await` keywords provide the translation every person makes to follow the written instructions: Start tasks as you can and don't block while waiting for tasks to complete.
-An async method can't declare [ByRef](../../../language-reference/modifiers/byref.md) parameters, but the method can call methods that have such parameters.
+## Async/await vs ContinueWith
-For more information and examples, see [Async Return Types (Visual Basic)](async-return-types.md). For more information about how to catch exceptions in async methods, see [Try...Catch...Finally Statement](../../../language-reference/statements/try-catch-finally-statement.md).
+The `Async` and `Await` keywords provide syntactic simplification over using directly. While `Async`/`Await` and `ContinueWith` have similar semantics for handling asynchronous operations, the compiler doesn't necessarily translate `Await` expressions directly into `ContinueWith` method calls. Instead, the compiler generates optimized state machine code that provides the same logical behavior. This transformation provides significant readability and maintainability benefits, especially when chaining multiple asynchronous operations.
-Asynchronous APIs in Windows Runtime programming have one of the following return types, which are similar to tasks:
+Consider a scenario where you need to perform multiple sequential asynchronous operations. Here's how the same logic looks when implemented with `ContinueWith` compared to `Async`/`Await`:
-- [IAsyncOperation(Of TResult)](xref:Windows.Foundation.IAsyncOperation%601), which corresponds to [Task(Of TResult)](xref:System.Threading.Tasks.Task%601)
-- , which corresponds to
-- [IAsyncActionWithProgress(Of TProgress)](xref:Windows.Foundation.IAsyncActionWithProgress%601)
-- [IAsyncOperationWithProgress(Of TResult, TProgress)](xref:Windows.Foundation.IAsyncOperationWithProgress%602)
+### Using ContinueWith
-For more information and an example, see [Call asynchronous APIs in C# or Visual Basic](/windows/uwp/threading-async/call-asynchronous-apis-in-csharp-or-visual-basic).
+With `ContinueWith`, each step in a sequence of asynchronous operations requires nested continuations:
-## Naming convention
+```vb
+' Using ContinueWith - demonstrates the complexity when chaining operations
+Function MakeBreakfastWithContinueWith() As Task
+ Return StartCookingEggsAsync() _
+ .ContinueWith(Function(eggsTask)
+ Dim eggs = eggsTask.Result
+ Console.WriteLine("Eggs ready, starting bacon...")
+ Return StartCookingBaconAsync()
+ End Function) _
+ .Unwrap() _
+ .ContinueWith(Function(baconTask)
+ Dim bacon = baconTask.Result
+ Console.WriteLine("Bacon ready, starting toast...")
+ Return StartToastingBreadAsync()
+ End Function) _
+ .Unwrap() _
+ .ContinueWith(Function(toastTask)
+ Dim toast = toastTask.Result
+ Console.WriteLine("Toast ready, applying butter...")
+ Return ApplyButterAsync(toast)
+ End Function) _
+ .Unwrap() _
+ .ContinueWith(Function(butteredToastTask)
+ Dim butteredToast = butteredToastTask.Result
+ Console.WriteLine("Butter applied, applying jam...")
+ Return ApplyJamAsync(butteredToast)
+ End Function) _
+ .Unwrap() _
+ .ContinueWith(Sub(finalToastTask)
+ Dim finalToast = finalToastTask.Result
+ Console.WriteLine("Breakfast completed with ContinueWith!")
+ End Sub)
+End Function
+```
-By convention, you append "Async" to the names of methods that have an `Async` modifier.
+### Using Async/Await
-You can ignore the convention where an event, base class, or interface contract suggests a different name. For example, you shouldn't rename common event handlers, such as `Button1_Click`.
+The same sequence of operations using `Async`/`Await` reads much more naturally:
-## Related topics and samples (Visual Studio)
+```vb
+' Using Async/Await - much cleaner and easier to read
+Async Function MakeBreakfastWithAsyncAwait() As Task
+ Dim eggs = Await StartCookingEggsAsync()
+ Console.WriteLine("Eggs ready, starting bacon...")
+
+ Dim bacon = Await StartCookingBaconAsync()
+ Console.WriteLine("Bacon ready, starting toast...")
+
+ Dim toast = Await StartToastingBreadAsync()
+ Console.WriteLine("Toast ready, applying butter...")
+
+ Dim butteredToast = Await ApplyButterAsync(toast)
+ Console.WriteLine("Butter applied, applying jam...")
+
+ Dim finalToast = Await ApplyJamAsync(butteredToast)
+ Console.WriteLine("Breakfast completed with Async/Await!")
+End Function
+```
-|Title|Description|Sample|
-|-----------|-----------------|------------|
-|[Walkthrough: Accessing the Web by Using Async and Await (Visual Basic)](walkthrough-accessing-the-web-by-using-async-and-await.md)|Shows how to convert a synchronous WPF solution to an asynchronous WPF solution. The application downloads a series of websites.|[Async Sample: Asynchronous Programming with Async and Await (Visual Basic)](/samples/dotnet/samples/async-and-await-vb/)|
-|[How to: Extend the Async Walkthrough by Using Task.WhenAll (Visual Basic)](how-to-extend-the-async-walkthrough-by-using-task-whenall.md)|Adds to the previous walkthrough. The use of `WhenAll` starts all the downloads at the same time.||
-|[How to: Make Multiple Web Requests in Parallel by Using Async and Await (Visual Basic)](how-to-make-multiple-web-requests-in-parallel-by-using-async-and-await.md)|Demonstrates how to start several tasks at the same time.|[Async Sample: Make Multiple Web Requests in Parallel](https://code.msdn.microsoft.com/Async-Make-Multiple-Web-49adb82e)|
-|[Async Return Types (Visual Basic)](async-return-types.md)|Illustrates the types that async methods can return and explains when each type is appropriate.||
-|[Control Flow in Async Programs (Visual Basic)](control-flow-in-async-programs.md)|Traces in detail the flow of control through a succession of await expressions in an asynchronous program.|[Async Sample: Control Flow in Async Programs](https://code.msdn.microsoft.com/Async-Sample-Control-Flow-5c804fc0)|
-|[Fine-Tuning Your Async Application (Visual Basic)](fine-tuning-your-async-application.md)|Shows how to add the following functionality to your async solution:
- [Cancel an Async Task or a List of Tasks (Visual Basic)](cancel-an-async-task-or-a-list-of-tasks.md)
- [Cancel Async Tasks after a Period of Time (Visual Basic)](cancel-async-tasks-after-a-period-of-time.md)
- [Cancel Remaining Async Tasks after One Is Complete (Visual Basic)](cancel-remaining-async-tasks-after-one-is-complete.md)
- [Start Multiple Async Tasks and Process Them As They Complete (Visual Basic)](start-multiple-async-tasks-and-process-them-as-they-complete.md)|[Async Sample: Fine Tuning Your Application](https://code.msdn.microsoft.com/Async-Fine-Tuning-Your-a676abea)|
-|[Handling Reentrancy in Async Apps (Visual Basic)](handling-reentrancy-in-async-apps.md)|Shows how to handle cases in which an active asynchronous operation is restarted while it's running.||
-|[WhenAny: Bridging between the .NET Framework and the Windows Runtime](/previous-versions/visualstudio/visual-studio-2013/jj635140(v=vs.120))|Shows how to bridge between Task types in the .NET Framework and IAsyncOperations in the Windows Runtime so that you can use with a Windows Runtime method.|[Async Sample: Bridging between .NET and Windows Runtime (AsTask and WhenAny)](/previous-versions/visualstudio/visual-studio-2013/jj635140(v=vs.120))|
-|Async Cancellation: Bridging between the .NET Framework and the Windows Runtime|Shows how to bridge between Task types in the .NET Framework and IAsyncOperations in the Windows Runtime so that you can use with a Windows Runtime method.|[Async Sample: Bridging between .NET and Windows Runtime (AsTask & Cancellation)](https://code.msdn.microsoft.com/Async-Sample-Bridging-9479eca3)|
-|[Using Async for File Access (Visual Basic)](using-async-for-file-access.md)|Lists and demonstrates the benefits of using async and await to access files.||
-|[Task-based Asynchronous Pattern (TAP)](../../../../standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap.md)|Describes a new pattern for asynchrony in the .NET Framework. The pattern is based on the and [Task(Of TResult)](xref:System.Threading.Tasks.Task%601) types.||
+### Why Async/Await is preferred
-## Complete Example
+The `Async`/`Await` approach offers several advantages:
-The following code is the MainWindow.xaml.vb file from the Windows Presentation Foundation (WPF) application that this topic discusses. You can download the sample from [Async Sample: Example from "Asynchronous Programming with Async and Await"](/samples/dotnet/samples/async-and-await-vb/).
+- **Readability**: The code reads like synchronous code, making it easier to understand the flow of operations.
+- **Maintainability**: Adding or removing steps in the sequence requires minimal code changes.
+- **Error handling**: Exception handling with `Try`/`Catch` blocks works naturally, whereas `ContinueWith` requires careful handling of faulted tasks.
+- **Debugging**: The call stack and debugger experience is much better with `Async`/`Await`.
+- **Performance**: The compiler optimizations for `Async`/`Await` are more sophisticated than manual `ContinueWith` chains.
-[!code-vb[async](~/samples/snippets/standard/async/async-and-await/vb/MainWindow.xaml.vb)]
+The benefit becomes even more apparent as the number of chained operations increases. While a single continuation might be manageable with `ContinueWith`, sequences of 3-4 or more asynchronous operations quickly become difficult to read and maintain. This pattern, known as "monadic do-notation" in functional programming, allows you to compose multiple asynchronous operations in a sequential, readable manner.
## See also
- [Await Operator](../../../language-reference/operators/await-operator.md)
- [Async](../../../language-reference/modifiers/async.md)
+- [Walkthrough: Accessing the Web by Using Async and Await (Visual Basic)](walkthrough-accessing-the-web-by-using-async-and-await.md)
+- [Async Return Types (Visual Basic)](async-return-types.md)
+- [Task-based Asynchronous Pattern (TAP)](/dotnet/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap)
diff --git a/docs/visual-basic/programming-guide/concepts/async/media/asynchronous-breakfast.png b/docs/visual-basic/programming-guide/concepts/async/media/asynchronous-breakfast.png
new file mode 100644
index 0000000000000..cc0882c14a019
Binary files /dev/null and b/docs/visual-basic/programming-guide/concepts/async/media/asynchronous-breakfast.png differ
diff --git a/docs/visual-basic/programming-guide/concepts/async/media/synchronous-breakfast.png b/docs/visual-basic/programming-guide/concepts/async/media/synchronous-breakfast.png
new file mode 100644
index 0000000000000..11d244ba785fc
Binary files /dev/null and b/docs/visual-basic/programming-guide/concepts/async/media/synchronous-breakfast.png differ
diff --git a/docs/visual-basic/programming-guide/concepts/async/media/whenany-async-breakfast.png b/docs/visual-basic/programming-guide/concepts/async/media/whenany-async-breakfast.png
new file mode 100644
index 0000000000000..df34c7f1be630
Binary files /dev/null and b/docs/visual-basic/programming-guide/concepts/async/media/whenany-async-breakfast.png differ
diff --git a/docs/visual-basic/programming-guide/concepts/async/snippets/breakfast/AsyncBreakfast.vb b/docs/visual-basic/programming-guide/concepts/async/snippets/breakfast/AsyncBreakfast.vb
new file mode 100644
index 0000000000000..7027c15d11c08
--- /dev/null
+++ b/docs/visual-basic/programming-guide/concepts/async/snippets/breakfast/AsyncBreakfast.vb
@@ -0,0 +1,81 @@
+Imports System
+Imports System.Collections.Generic
+Imports System.Threading.Tasks
+
+'
+Module AsyncBreakfastProgram
+ Async Function Main() As Task
+ Dim cup As Coffee = PourCoffee()
+ Console.WriteLine("coffee is ready")
+
+ Dim eggs As Egg = Await FryEggsAsync(2)
+ Console.WriteLine("eggs are ready")
+
+ Dim hashBrown As HashBrown = Await FryHashBrownsAsync(3)
+ Console.WriteLine("hash browns are ready")
+
+ Dim toast As Toast = Await ToastBreadAsync(2)
+ ApplyButter(toast)
+ ApplyJam(toast)
+ Console.WriteLine("toast is ready")
+
+ Dim oj As Juice = PourOJ()
+ Console.WriteLine("oj is ready")
+ Console.WriteLine("Breakfast is ready!")
+ End Function
+
+ Private Async Function ToastBreadAsync(slices As Integer) As Task(Of Toast)
+ For slice As Integer = 0 To slices - 1
+ Console.WriteLine("Putting a slice of bread in the toaster")
+ Next
+ Console.WriteLine("Start toasting...")
+ Await Task.Delay(3000)
+ Console.WriteLine("Remove toast from toaster")
+
+ Return New Toast()
+ End Function
+
+ Private Async Function FryHashBrownsAsync(patties As Integer) As Task(Of HashBrown)
+ Console.WriteLine($"putting {patties} hash brown patties in the pan")
+ Console.WriteLine("cooking first side of hash browns...")
+ Await Task.Delay(3000)
+ For patty As Integer = 0 To patties - 1
+ Console.WriteLine("flipping a hash brown patty")
+ Next
+ Console.WriteLine("cooking the second side of hash browns...")
+ Await Task.Delay(3000)
+ Console.WriteLine("Put hash browns on plate")
+
+ Return New HashBrown()
+ End Function
+
+ Private Async Function FryEggsAsync(howMany As Integer) As Task(Of Egg)
+ Console.WriteLine("Warming the egg pan...")
+ Await Task.Delay(3000)
+ Console.WriteLine($"cracking {howMany} eggs")
+ Console.WriteLine("cooking the eggs ...")
+ Await Task.Delay(3000)
+ Console.WriteLine("Put eggs on plate")
+
+ Return New Egg()
+ End Function
+
+ Private Function PourCoffee() As Coffee
+ Console.WriteLine("Pouring coffee")
+ Return New Coffee()
+ End Function
+
+ Private Function PourOJ() As Juice
+ Console.WriteLine("Pouring orange juice")
+ Return New Juice()
+ End Function
+
+ Private Sub ApplyJam(toast As Toast)
+ Console.WriteLine("Putting jam on the toast")
+ End Sub
+
+ Private Sub ApplyButter(toast As Toast)
+ Console.WriteLine("Putting butter on the toast")
+ End Sub
+End Module
+'
\ No newline at end of file
diff --git a/docs/visual-basic/programming-guide/concepts/async/snippets/breakfast/ConcurrentBreakfast.vb b/docs/visual-basic/programming-guide/concepts/async/snippets/breakfast/ConcurrentBreakfast.vb
new file mode 100644
index 0000000000000..c31334ad6759f
--- /dev/null
+++ b/docs/visual-basic/programming-guide/concepts/async/snippets/breakfast/ConcurrentBreakfast.vb
@@ -0,0 +1,96 @@
+Imports System
+Imports System.Collections.Generic
+Imports System.Threading.Tasks
+
+'
+Module ConcurrentBreakfastProgram
+ Async Function Main() As Task
+ Dim cup As Coffee = PourCoffee()
+ Console.WriteLine("Coffee is ready")
+
+ Dim eggsTask As Task(Of Egg) = FryEggsAsync(2)
+ Dim hashBrownTask As Task(Of HashBrown) = FryHashBrownsAsync(3)
+ Dim toastTask As Task(Of Toast) = MakeToastWithButterAndJamAsync(2)
+
+ Dim breakfastTasks As New List(Of Task) From {eggsTask, hashBrownTask, toastTask}
+ While breakfastTasks.Count > 0
+ Dim finishedTask As Task = Await Task.WhenAny(breakfastTasks)
+ If finishedTask Is eggsTask Then
+ Console.WriteLine("eggs are ready")
+ ElseIf finishedTask Is hashBrownTask Then
+ Console.WriteLine("hash browns are ready")
+ ElseIf finishedTask Is toastTask Then
+ Console.WriteLine("toast is ready")
+ End If
+ Await finishedTask
+ breakfastTasks.Remove(finishedTask)
+ End While
+
+ Dim oj As Juice = PourOJ()
+ Console.WriteLine("oj is ready")
+ Console.WriteLine("Breakfast is ready!")
+ End Function
+
+ Async Function MakeToastWithButterAndJamAsync(number As Integer) As Task(Of Toast)
+ Dim toast As Toast = Await ToastBreadAsync(number)
+ ApplyButter(toast)
+ ApplyJam(toast)
+
+ Return toast
+ End Function
+
+ Private Async Function ToastBreadAsync(slices As Integer) As Task(Of Toast)
+ For slice As Integer = 0 To slices - 1
+ Console.WriteLine("Putting a slice of bread in the toaster")
+ Next
+ Console.WriteLine("Start toasting...")
+ Await Task.Delay(3000)
+ Console.WriteLine("Remove toast from toaster")
+
+ Return New Toast()
+ End Function
+
+ Private Async Function FryHashBrownsAsync(patties As Integer) As Task(Of HashBrown)
+ Console.WriteLine($"putting {patties} hash brown patties in the pan")
+ Console.WriteLine("cooking first side of hash browns...")
+ Await Task.Delay(3000)
+ For patty As Integer = 0 To patties - 1
+ Console.WriteLine("flipping a hash brown patty")
+ Next
+ Console.WriteLine("cooking the second side of hash browns...")
+ Await Task.Delay(3000)
+ Console.WriteLine("Put hash browns on plate")
+
+ Return New HashBrown()
+ End Function
+
+ Private Async Function FryEggsAsync(howMany As Integer) As Task(Of Egg)
+ Console.WriteLine("Warming the egg pan...")
+ Await Task.Delay(3000)
+ Console.WriteLine($"cracking {howMany} eggs")
+ Console.WriteLine("cooking the eggs ...")
+ Await Task.Delay(3000)
+ Console.WriteLine("Put eggs on plate")
+
+ Return New Egg()
+ End Function
+
+ Private Function PourCoffee() As Coffee
+ Console.WriteLine("Pouring coffee")
+ Return New Coffee()
+ End Function
+
+ Private Function PourOJ() As Juice
+ Console.WriteLine("Pouring orange juice")
+ Return New Juice()
+ End Function
+
+ Private Sub ApplyJam(toast As Toast)
+ Console.WriteLine("Putting jam on the toast")
+ End Sub
+
+ Private Sub ApplyButter(toast As Toast)
+ Console.WriteLine("Putting butter on the toast")
+ End Sub
+End Module
+'
\ No newline at end of file
diff --git a/docs/visual-basic/programming-guide/concepts/async/snippets/breakfast/Program.vb b/docs/visual-basic/programming-guide/concepts/async/snippets/breakfast/Program.vb
new file mode 100644
index 0000000000000..fd2ae23bb09af
--- /dev/null
+++ b/docs/visual-basic/programming-guide/concepts/async/snippets/breakfast/Program.vb
@@ -0,0 +1,97 @@
+Imports System
+Imports System.Collections.Generic
+Imports System.Threading.Tasks
+
+' These classes are intentionally empty for the purpose of this example. They are simply marker classes for the purpose of demonstration, contain no properties, and serve no other purpose.
+Friend Class HashBrown
+End Class
+
+Friend Class Coffee
+End Class
+
+Friend Class Egg
+End Class
+
+Friend Class Juice
+End Class
+
+Friend Class Toast
+End Class
+
+Module Program
+ '
+ Sub Main()
+ Dim cup As Coffee = PourCoffee()
+ Console.WriteLine("coffee is ready")
+
+ Dim eggs As Egg = FryEggs(2)
+ Console.WriteLine("eggs are ready")
+
+ Dim hashBrown As HashBrown = FryHashBrowns(3)
+ Console.WriteLine("hash browns are ready")
+
+ Dim toast As Toast = ToastBread(2)
+ ApplyButter(toast)
+ ApplyJam(toast)
+ Console.WriteLine("toast is ready")
+
+ Dim oj As Juice = PourOJ()
+ Console.WriteLine("oj is ready")
+ Console.WriteLine("Breakfast is ready!")
+ End Sub
+
+ Private Function PourOJ() As Juice
+ Console.WriteLine("Pouring orange juice")
+ Return New Juice()
+ End Function
+
+ Private Sub ApplyJam(toast As Toast)
+ Console.WriteLine("Putting jam on the toast")
+ End Sub
+
+ Private Sub ApplyButter(toast As Toast)
+ Console.WriteLine("Putting butter on the toast")
+ End Sub
+
+ Private Function ToastBread(slices As Integer) As Toast
+ For slice As Integer = 0 To slices - 1
+ Console.WriteLine("Putting a slice of bread in the toaster")
+ Next
+ Console.WriteLine("Start toasting...")
+ Task.Delay(3000).Wait()
+ Console.WriteLine("Remove toast from toaster")
+
+ Return New Toast()
+ End Function
+
+ Private Function FryHashBrowns(patties As Integer) As HashBrown
+ Console.WriteLine($"putting {patties} hash brown patties in the pan")
+ Console.WriteLine("cooking first side of hash browns...")
+ Task.Delay(3000).Wait()
+ For patty As Integer = 0 To patties - 1
+ Console.WriteLine("flipping a hash brown patty")
+ Next
+ Console.WriteLine("cooking the second side of hash browns...")
+ Task.Delay(3000).Wait()
+ Console.WriteLine("Put hash browns on plate")
+
+ Return New HashBrown()
+ End Function
+
+ Private Function FryEggs(howMany As Integer) As Egg
+ Console.WriteLine("Warming the egg pan...")
+ Task.Delay(3000).Wait()
+ Console.WriteLine($"cracking {howMany} eggs")
+ Console.WriteLine("cooking the eggs ...")
+ Task.Delay(3000).Wait()
+ Console.WriteLine("Put eggs on plate")
+
+ Return New Egg()
+ End Function
+
+ Private Function PourCoffee() As Coffee
+ Console.WriteLine("Pouring coffee")
+ Return New Coffee()
+ End Function
+ '
+End Module
\ No newline at end of file
diff --git a/docs/visual-basic/programming-guide/concepts/async/snippets/breakfast/breakfast.vbproj b/docs/visual-basic/programming-guide/concepts/async/snippets/breakfast/breakfast.vbproj
new file mode 100644
index 0000000000000..aee73149c0567
--- /dev/null
+++ b/docs/visual-basic/programming-guide/concepts/async/snippets/breakfast/breakfast.vbproj
@@ -0,0 +1,8 @@
+
+
+
+ Exe
+ net9.0
+
+
+
\ No newline at end of file
diff --git a/includes/templates.md b/includes/templates.md
deleted file mode 100644
index 6ff82c69199e5..0000000000000
--- a/includes/templates.md
+++ /dev/null
@@ -1,52 +0,0 @@
-The following table shows the templates that come pre-installed with the .NET SDK. The default language for the template is shown inside the brackets. Click on the short name link to see the specific template options.
-
-| Templates | Short name | Language | Tags | Introduced |
-|----------------------------------------------|-------------------------------------------------------------------------------------|--------------|---------------------------------------|------------------|
-| Console Application | [`console`](../docs/core/tools/dotnet-new-sdk-templates.md#console) | [C#], F#, VB | Common/Console | 1.0 |
-| Class library | [`classlib`](../docs/core/tools/dotnet-new-sdk-templates.md#classlib) | [C#], F#, VB | Common/Library | 1.0 |
-| WPF Application | [`wpf`](../docs/core/tools/dotnet-new-sdk-templates.md#wpf) | [C#], VB | Common/WPF | 3.0 (5.0 for VB) |
-| WPF Class library | [`wpflib`](../docs/core/tools/dotnet-new-sdk-templates.md#wpf) | [C#], VB | Common/WPF | 3.0 (5.0 for VB) |
-| WPF Custom Control Library | [`wpfcustomcontrollib`](../docs/core/tools/dotnet-new-sdk-templates.md#wpf) | [C#], VB | Common/WPF | 3.0 (5.0 for VB) |
-| WPF User Control Library | [`wpfusercontrollib`](../docs/core/tools/dotnet-new-sdk-templates.md#wpf) | [C#], VB | Common/WPF | 3.0 (5.0 for VB) |
-| Windows Forms (WinForms) Application | [`winforms`](../docs/core/tools/dotnet-new-sdk-templates.md#winforms) | [C#], VB | Common/WinForms | 3.0 (5.0 for VB) |
-| Windows Forms (WinForms) Class library | [`winformslib`](../docs/core/tools/dotnet-new-sdk-templates.md#winforms) | [C#], VB | Common/WinForms | 3.0 (5.0 for VB) |
-| Worker Service | [`worker`](../docs/core/tools/dotnet-new-sdk-templates.md#web-others) | [C#] | Common/Worker/Web | 3.0 |
-| MSTest Test Project | [`mstest`](../docs/core/tools/dotnet-new-sdk-templates.md#mstest) | [C#], F#, VB | Test/MSTest | 1.0 |
-| MSTest Test Class | [`mstest-class`](../docs/core/tools/dotnet-new-sdk-templates.md#mstest-class) | [C#], F#, VB | Test/MSTest | 1.0 |
-| NUnit 3 Test Project | [`nunit`](../docs/core/tools/dotnet-new-sdk-templates.md#nunit) | [C#], F#, VB | Test/NUnit | 2.1.400 |
-| NUnit 3 Test Item | `nunit-test` | [C#], F#, VB | Test/NUnit | 2.2 |
-| xUnit Test Project | [`xunit`](../docs/core/tools/dotnet-new-sdk-templates.md#xunit) | [C#], F#, VB | Test/xUnit | 1.0 |
-| Razor Component | `razorcomponent` | [C#] | Web/ASP.NET | 3.0 |
-| Razor Page | [`page`](../docs/core/tools/dotnet-new-sdk-templates.md#page) | [C#] | Web/ASP.NET | 2.0 |
-| MVC ViewImports | [`viewimports`](../docs/core/tools/dotnet-new-sdk-templates.md#namespace) | [C#] | Web/ASP.NET | 2.0 |
-| MVC ViewStart | `viewstart` | [C#] | Web/ASP.NET | 2.0 |
-| Blazor Web App | [`blazor`](../docs/core/tools/dotnet-new-sdk-templates.md#blazor) | [C#] | Web/Blazor | 8.0.100 |
-| Blazor WebAssembly Standalone App | [`blazorwasm`](../docs/core/tools/dotnet-new-sdk-templates.md#blazorwasm) | [C#] | Web/Blazor/WebAssembly/PWA | 3.1.300 |
-| ASP.NET Core Empty | [`web`](../docs/core/tools/dotnet-new-sdk-templates.md#web) | [C#], F# | Web/Empty | 1.0 |
-| ASP.NET Core Web App (Model-View-Controller) | [`mvc`](../docs/core/tools/dotnet-new-sdk-templates.md#web-options) | [C#], F# | Web/MVC | 1.0 |
-| ASP.NET Core Web App | [`webapp, razor`](../docs/core/tools/dotnet-new-sdk-templates.md#web-options) | [C#] | Web/MVC/Razor Pages | 2.2, 2.0 |
-| Razor Class Library | [`razorclasslib`](../docs/core/tools/dotnet-new-sdk-templates.md#razorclasslib) | [C#] | Web/Razor/Library/Razor Class Library | 2.1 |
-| ASP.NET Core Web API | [`webapi`](../docs/core/tools/dotnet-new-sdk-templates.md#webapi) | [C#], F# | Web/Web API/API/Service/WebAPI | 1.0 |
-| ASP.NET Core API | [`webapiaot`](../docs/core/tools/dotnet-new-sdk-templates.md#webapiaot) | [C#] | Web/Web API/API/Service | 8.0 |
-| ASP.NET Core API controller | [`apicontroller`](../docs/core/tools/dotnet-new-sdk-templates.md#apicontroller) | [C#] | Web/ASP.NET | 8.0 |
-| ASP.NET Core gRPC Service | [`grpc`](../docs/core/tools/dotnet-new-sdk-templates.md#web-others) | [C#] | Web/gRPC | 3.0 |
-| dotnet gitignore file | `gitignore` | | Config | 3.0 |
-| global.json file | [`globaljson`](../docs/core/tools/dotnet-new-sdk-templates.md#globaljson) | | Config | 2.0 |
-| NuGet Config | `nugetconfig` | | Config | 1.0 |
-| Dotnet local tool manifest file | `tool-manifest` | | Config | 3.0 |
-| Web Config | `webconfig` | | Config | 1.0 |
-| Directory.Build.props file | [`buildprops`](../docs/core/tools/dotnet-new-sdk-templates.md#buildprops) | | Config | 8.0.100 |
-| Directory.Build.targets file | [`buildtargets`](../docs/core/tools/dotnet-new-sdk-templates.md#buildtargets) | | Config | 8.0.100 |
-| Solution File | [`sln`](../docs/core/tools/dotnet-new-sdk-templates.md#sln) | | Solution | 1.0 |
-| Protocol Buffer File | [`proto`](../docs/core/tools/dotnet-new-sdk-templates.md#namespace) | | Web/gRPC | 3.0 |
-| EditorConfig file | [`editorconfig`](../docs/core/tools/dotnet-new-sdk-templates.md#editorconfig) | | Config | 6.0 |
-
-The following table shows templates that have been discontinued and no longer come pre-installed with the .NET SDK. Click on the short name link to see the specific template options.
-
-| Templates | Short name | Language | Tags | Discontinued since |
-|----------------------------------------------|-------------------------------------------------------------------------------------|--------------|---------------------------------------|------------------|
-| ASP.NET Core with Angular | [`angular`](../docs/core/tools/dotnet-new-sdk-templates.md#spa) | [C#] | Web/MVC/SPA | 8.0 |
-| ASP.NET Core with React.js | [`react`](../docs/core/tools/dotnet-new-sdk-templates.md#spa) | [C#] | Web/MVC/SPA | 8.0 |
-| Blazor Server App | [`blazorserver`](../docs/core/tools/dotnet-new-sdk-templates.md#blazorserver) | [C#] | Web/Blazor | 8.0 |
-| Blazor Server App Empty | [`blazorserver-empty`](../docs/core/tools/dotnet-new-sdk-templates.md#blazorserver) | [C#] | Web/Blazor | 8.0 |
-| Blazor WebAssembly App Empty | [`blazorwasm-empty`](../docs/core/tools/dotnet-new-sdk-templates.md#blazorwasm) | [C#] | Web/Blazor/WebAssembly | 8.0 |
diff --git a/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbvbalrwithstatement/vb/mainwindow.xaml.vb b/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbvbalrwithstatement/vb/mainwindow.xaml.vb
index 13409d329f7c0..ef85a5dc5c7b5 100644
--- a/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbvbalrwithstatement/vb/mainwindow.xaml.vb
+++ b/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbvbalrwithstatement/vb/mainwindow.xaml.vb
@@ -51,5 +51,46 @@
End Class
'
+ '
+ Private Sub DemonstrateStructureWithStatement()
+ ' Create an array of structures - this is referenceable
+ Dim points(2) As Point
+
+ ' Valid: Array elements are referenceable, so assignments work
+ With points(0)
+ .X = 10
+ .Y = 20
+ End With
+
+ ' Create a single structure variable - this is also referenceable
+ Dim singlePoint As Point
+ With singlePoint
+ .X = 30
+ .Y = 40
+ End With
+
+ ' Invalid: Using parentheses cuts reference ties
+ ' With (points(0))
+ ' .X = 50 ' This would cause BC30068 error
+ ' .Y = 60
+ ' End With
+
+ ' Invalid: Function returns by value, not referenceable
+ ' With GetPoint()
+ ' .X = 70 ' This would cause BC30068 error
+ ' .Y = 80
+ ' End With
+ End Sub
+
+ Private Function GetPoint() As Point
+ Return New Point With {.X = 1, .Y = 2}
+ End Function
+
+ Private Structure Point
+ Public X As Integer
+ Public Y As Integer
+ End Structure
+ '
+
End Class
diff --git a/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbvbalrwithstatement/vb/snippets.5000.json b/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbvbalrwithstatement/vb/snippets.5000.json
new file mode 100644
index 0000000000000..9493e733615c7
--- /dev/null
+++ b/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbvbalrwithstatement/vb/snippets.5000.json
@@ -0,0 +1,3 @@
+{
+ "host": "visualstudio"
+}
\ No newline at end of file
diff --git a/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbvbalrwithstatement/vb/vbwpfapp.vbproj b/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbvbalrwithstatement/vb/vbwpfapp.vbproj
index f2a83367e66fa..5ea423e4e12de 100644
--- a/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbvbalrwithstatement/vb/vbwpfapp.vbproj
+++ b/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbvbalrwithstatement/vb/vbwpfapp.vbproj
@@ -8,8 +8,7 @@
WinExe
VBWPFApp
VBWPFApp
- v4.0
- Client
+ v4.8
Custom