Skip to content

Commit e574c8f

Browse files
Merge pull request #47385 from dotnet/main
Merge main into live
2 parents 62229aa + fc4883b commit e574c8f

File tree

23 files changed

+524
-248
lines changed

23 files changed

+524
-248
lines changed

docs/ai/get-started-app-chat-template.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ The architecture of the chat app is shown in the following diagram:
3939

4040
- **User interface** - The application's chat interface is a [Blazor WebAssembly](/aspnet/core/blazor/) application. This interface is what accepts user queries, routes request to the application backend, and displays generated responses.
4141
- **Backend** - The application backend is an [ASP.NET Core Minimal API](/aspnet/core/fundamentals/minimal-apis/overview). The backend hosts the Blazor static web application and is what orchestrates the interactions among the different services. Services used in this application include:
42-
- [**Azure Cognitive Search**](/azure/search/search-what-is-azure-search) – Indexes documents from the data stored in an Azure Storage Account. This makes the documents searchable using [vector search](/azure/search/search-get-started-vector) capabilities.
42+
- [**Azure AI Search**](/azure/search/search-what-is-azure-search) – Indexes documents from the data stored in an Azure Storage Account. This makes the documents searchable using [vector search](/azure/search/search-get-started-vector) capabilities.
4343
- [**Azure OpenAI Service**](/azure/ai-services/openai/overview) – Provides the Large Language Models (LLM) to generate responses. [Semantic Kernel](/semantic-kernel/whatissk) is used in conjunction with the Azure OpenAI Service to orchestrate the more complex AI workflows.
4444

4545
## Cost

docs/csharp/advanced-topics/interface-implementation/default-interface-methods-versions.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ First, add the new method to the interface, including the body of the method:
4747

4848
:::code language="csharp" source="./snippets/default-interface-members-versions/finished/customer-relationship/ICustomer.cs" id="SnippetLoyaltyDiscountVersionOne":::
4949

50+
> [!NOTE]
51+
> The preceding example uses `DateTime.Now.AddYears(-2)` for simplicity in this tutorial. Be aware that `DateTime` calculations can have edge cases with daylight saving time transitions and leap years. For production code, consider using UTC time or more robust date calculation approaches when precision is important.
52+
5053
The library author wrote a first test to check the implementation:
5154

5255
:::code language="csharp" source="./snippets/default-interface-members-versions/finished/customer-relationship/Program.cs" id="SnippetTestDefaultImplementation":::

docs/csharp/asynchronous-programming/index.md

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@ The task asynchronous programming model is analogous to how people give instruct
1111

1212
1. Pour a cup of coffee.
1313
1. Heat a pan, then fry two eggs.
14-
1. Fry three slices of bacon.
14+
1. Cook three hash brown patties.
1515
1. Toast two pieces of bread.
1616
1. Spread butter and jam on the toast.
1717
1. Pour a glass of orange juice.
1818

19-
If you have experience with cooking, you might complete these instructions **asynchronously**. You start warming the pan for eggs, then start frying the bacon. 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.
19+
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.
2020

21-
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 frying the bacon. After the bacon starts to cook, you can put the bread in the toaster.
21+
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.
2222

23-
For a parallel algorithm, you need multiple people who cook (or multiple threads). One person cooks the eggs, another fries the bacon, 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: Bacon ready to flip, bread ready to pop up in toaster, and so on.
23+
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.
2424

2525
:::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.":::
2626

@@ -42,20 +42,20 @@ You can start by updating the code so the thread doesn't block while tasks are r
4242

4343
:::code language="csharp" source="snippets/index/AsyncBreakfast-V2/Program.cs" ID="SnippetMain":::
4444

45-
The code updates the original method bodies of `FryEggs`, `FryBacon`, and `ToastBread` to return `Task<Egg>`, `Task<Bacon>`, and `Task<Toast>` objects, respectively. The updated method names include the "Async" suffix: `FryEggsAsync`, `FryBaconAsync`, and `ToastBreadAsync`. The `Main` method returns the `Task` object, although it doesn't have a `return` expression, which is by design. For more information, see [Evaluation of a void-returning async function](/dotnet/csharp/language-reference/language-specification/classes#15144-evaluation-of-a-void-returning-async-function).
45+
The code updates the original method bodies of `FryEggs`, `FryHashBrowns`, and `ToastBread` to return `Task<Egg>`, `Task<HashBrown>`, and `Task<Toast>` objects, respectively. The updated method names include the "Async" suffix: `FryEggsAsync`, `FryHashBrownsAsync`, and `ToastBreadAsync`. The `Main` method returns the `Task` object, although it doesn't have a `return` expression, which is by design. For more information, see [Evaluation of a void-returning async function](/dotnet/csharp/language-reference/language-specification/classes#15144-evaluation-of-a-void-returning-async-function).
4646

4747
> [!NOTE]
4848
> 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](#review-final-code) later in this article.
4949
50-
Let's apply the breakfast example to the updated code. The thread doesn't block while the eggs or bacon 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.
50+
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.
5151

5252
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.
5353

5454
## Start tasks concurrently
5555

5656
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.
5757

58-
The <xref:System.Threading.Tasks.Task?displayProperty=nameWithType> 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, bacon, 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.
58+
The <xref:System.Threading.Tasks.Task?displayProperty=nameWithType> 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.
5959

6060
In your code, you start a task and hold on to the <xref:System.Threading.Tasks.Task> object that represents the work. You use the `await` method on the task to delay acting on the work until the result is ready.
6161

@@ -69,9 +69,9 @@ Task<Egg> eggsTask = FryEggsAsync(2);
6969
Egg eggs = await eggsTask;
7070
Console.WriteLine("Eggs are ready");
7171

72-
Task<Bacon> baconTask = FryBaconAsync(3);
73-
Bacon bacon = await baconTask;
74-
Console.WriteLine("Bacon is ready");
72+
Task<HashBrown> hashBrownTask = FryHashBrownsAsync(3);
73+
HashBrown hashBrown = await hashBrownTask;
74+
Console.WriteLine("Hash browns are ready");
7575

7676
Task<Toast> toastTask = ToastBreadAsync(2);
7777
Toast toast = await toastTask;
@@ -84,14 +84,14 @@ Console.WriteLine("Oj is ready");
8484
Console.WriteLine("Breakfast is ready!");
8585
```
8686

87-
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 bacon and eggs to the end of the method, before you serve the breakfast:
87+
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:
8888

8989
```csharp
9090
Coffee cup = PourCoffee();
9191
Console.WriteLine("Coffee is ready");
9292

9393
Task<Egg> eggsTask = FryEggsAsync(2);
94-
Task<Bacon> baconTask = FryBaconAsync(3);
94+
Task<HashBrown> hashBrownTask = FryHashBrownsAsync(3);
9595
Task<Toast> toastTask = ToastBreadAsync(2);
9696

9797
Toast toast = await toastTask;
@@ -103,17 +103,17 @@ Console.WriteLine("Oj is ready");
103103

104104
Egg eggs = await eggsTask;
105105
Console.WriteLine("Eggs are ready");
106-
Bacon bacon = await baconTask;
107-
Console.WriteLine("Bacon is ready");
106+
HashBrown hashBrown = await hashBrownTask;
107+
Console.WriteLine("Hash browns are ready");
108108

109109
Console.WriteLine("Breakfast is ready!");
110110
```
111111

112112
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.
113113

114-
:::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 bacon burn.":::
114+
:::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.":::
115115

116-
The code updates improve the preparation process by reducing the cook time, but they introduce a regression by burning the eggs and bacon. 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.
116+
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.
117117

118118
## Support composition with tasks
119119

@@ -169,22 +169,22 @@ After you make the code changes, run the application and check the output:
169169
Pouring coffee
170170
Coffee is ready
171171
Warming the egg pan...
172-
putting 3 slices of bacon in the pan
173-
Cooking first side of bacon...
172+
putting 3 hash brown patties in the pan
173+
Cooking first side of hash browns...
174174
Putting a slice of bread in the toaster
175175
Putting a slice of bread in the toaster
176176
Start toasting...
177177
Fire! Toast is ruined!
178-
Flipping a slice of bacon
179-
Flipping a slice of bacon
180-
Flipping a slice of bacon
181-
Cooking the second side of bacon...
178+
Flipping a hash brown patty
179+
Flipping a hash brown patty
180+
Flipping a hash brown patty
181+
Cooking the second side of hash browns...
182182
Cracking 2 eggs
183183
Cooking the eggs ...
184-
Put bacon on plate
184+
Put hash browns on plate
185185
Put eggs on plate
186186
Eggs are ready
187-
Bacon is ready
187+
Hash browns are ready
188188
Unhandled exception. System.InvalidOperationException: The toaster is on fire
189189
at AsyncBreakfast.Program.ToastBreadAsync(Int32 slices) in Program.cs:line 65
190190
at AsyncBreakfast.Program.MakeToastWithButterAndJamAsync(Int32 number) in Program.cs:line 36
@@ -218,27 +218,27 @@ throw new InvalidOperationException("The toaster is on fire");
218218
You can improve the series of `await` expressions at the end of the previous code by using methods of the `Task` class. One API is the <xref:System.Threading.Tasks.Task.WhenAll%2A> method, which returns a <xref:System.Threading.Tasks.Task> object that completes when all the tasks in its argument list are complete. The following code demonstrates this method:
219219

220220
```csharp
221-
await Task.WhenAll(eggsTask, baconTask, toastTask);
221+
await Task.WhenAll(eggsTask, hashBrownTask, toastTask);
222222
Console.WriteLine("Eggs are ready");
223-
Console.WriteLine("Bacon is ready");
223+
Console.WriteLine("Hash browns are ready");
224224
Console.WriteLine("Toast is ready");
225225
Console.WriteLine("Breakfast is ready!");
226226
```
227227

228228
Another option is to use the <xref:System.Threading.Tasks.Task.WhenAny%2A> method, which returns a `Task<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 <xref:System.Threading.Tasks.Task.WhenAny%2A> 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.
229229

230230
```csharp
231-
var breakfastTasks = new List<Task> { eggsTask, baconTask, toastTask };
231+
var breakfastTasks = new List<Task> { eggsTask, hashBrownTask, toastTask };
232232
while (breakfastTasks.Count > 0)
233233
{
234234
Task finishedTask = await Task.WhenAny(breakfastTasks);
235235
if (finishedTask == eggsTask)
236236
{
237237
Console.WriteLine("Eggs are ready");
238238
}
239-
else if (finishedTask == baconTask)
239+
else if (finishedTask == hashBrownTask)
240240
{
241-
Console.WriteLine("Bacon is ready");
241+
Console.WriteLine("Hash browns are ready");
242242
}
243243
else if (finishedTask == toastTask)
244244
{

docs/csharp/asynchronous-programming/snippets/index/AsyncBreakfast-V2/Program.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace AsyncBreakfast
66
class Program
77
{
88
// 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.
9-
internal class Bacon { }
9+
internal class HashBrown { }
1010
internal class Coffee { }
1111
internal class Egg { }
1212
internal class Juice { }
@@ -21,8 +21,8 @@ static async Task Main(string[] args)
2121
Egg eggs = await FryEggsAsync(2);
2222
Console.WriteLine("eggs are ready");
2323

24-
Bacon bacon = await FryBaconAsync(3);
25-
Console.WriteLine("bacon is ready");
24+
HashBrown hashBrown = await FryHashBrownsAsync(3);
25+
Console.WriteLine("hash browns are ready");
2626

2727
Toast toast = await ToastBreadAsync(2);
2828
ApplyButter(toast);
@@ -60,20 +60,20 @@ private static async Task<Toast> ToastBreadAsync(int slices)
6060
return new Toast();
6161
}
6262

63-
private static async Task<Bacon> FryBaconAsync(int slices)
63+
private static async Task<HashBrown> FryHashBrownsAsync(int patties)
6464
{
65-
Console.WriteLine($"putting {slices} slices of bacon in the pan");
66-
Console.WriteLine("cooking first side of bacon...");
65+
Console.WriteLine($"putting {patties} hash brown patties in the pan");
66+
Console.WriteLine("cooking first side of hash browns...");
6767
await Task.Delay(3000);
68-
for (int slice = 0; slice < slices; slice++)
68+
for (int patty = 0; patty < patties; patty++)
6969
{
70-
Console.WriteLine("flipping a slice of bacon");
70+
Console.WriteLine("flipping a hash brown patty");
7171
}
72-
Console.WriteLine("cooking the second side of bacon...");
72+
Console.WriteLine("cooking the second side of hash browns...");
7373
await Task.Delay(3000);
74-
Console.WriteLine("Put bacon on plate");
74+
Console.WriteLine("Put hash browns on plate");
7575

76-
return new Bacon();
76+
return new HashBrown();
7777
}
7878

7979
private static async Task<Egg> FryEggsAsync(int howMany)

0 commit comments

Comments
 (0)