.NET 9 引入了几个新的线程功能,这些功能简化了开发人员使用异步任务和通道的方式。在本文中,我们将探讨新的 API 和添加的优先无界通道,并提供代码示例来演示它们的用法。Task.WhenEach
最有用的新增功能之一是 API。以前,在任务完成时迭代任务需要复杂的模式,例如调用以检索下一个已完成的任务。Task.WhenEachTask.WaitAny
借助 ,您可以使用循环在任务完成时迭代任务,从而显著简化任务管理。Task.WhenEachawait foreach
我们来看看这个 API 在进行异步 I/O 调用的实际场景中是如何工作的。
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
using HttpClient httpClient = new HttpClient();
// Example URLs to fetch data from
Task<string> firstTask = httpClient.GetStringAsync("https://api.github.com");
Task<string> secondTask = httpClient.GetStringAsync("https://jsonplaceholder.typicode.com/posts/1");
Task<string> thirdTask = httpClient.GetStringAsync("https://jsonplaceholder.typicode.com/posts/2");
// Use Task.WhenEach to process tasks as they complete
await foreach (Task<string> completedTask in Task.WhenEach(firstTask, secondTask, thirdTask))
{
try
{
Console.WriteLine($"Response Length: {completedTask.Result.Length}");
}
catch (Exception ex)
{
Console.WriteLine($"Task encountered an error: {ex.Message}");
}
}
}
}
这个新的 API 非常适合需要在任务结果可用时立即对任务结果执行操作,而不必等待所有任务完成的情况。
在 .NET 中,通道是用于程序不同部分之间通信的数据结构。它通常用于具有多个生产者(添加数据)和使用者(处理数据)的场景。通道的工作方式与队列类似,但它们对数据的处理方式提供了更多控制,尤其是在并发或多线程环境中。
通道允许在不同任务之间进行安全、线程友好的通信。两种主要类型的通道是:
默认情况下,渠道按添加顺序 (FIFO) 处理项目。但是,随着 .NET 9 中引入优先通道,您现在可以根据优先级处理项目,而不仅仅是根据项目的添加顺序。
以下是优先渠道的运作方式细分:
using System;
using System.Threading.Channels;
using System.Threading.Tasks;
using System.Collections.Generic;
class Program
{
static async Task Main(string[] args)
{
// Create a channel that prioritizes smaller numbers (lower numbers processed first)
Channel<int> priorityChannel = Channel.CreateUnboundedPrioritized<int>(Comparer<int>.Create((x, y) => x.CompareTo(y)));
// Add numbers in random order
await priorityChannel.Writer.WriteAsync(10);
await priorityChannel.Writer.WriteAsync(3);
await priorityChannel.Writer.WriteAsync(7);
// Complete the writer so no more data is written
priorityChannel.Writer.Complete();
// Read items from the channel in prioritized order (smallest to largest)
while (await priorityChannel.Reader.WaitToReadAsync())
{
while (priorityChannel.Reader.TryRead(out int item))
{
Console.WriteLine($"Processed item: {item}");
}
}
}
}
从通道读取项目时,首先处理较小的数字 (3),然后是 7,最后是 10。