合并2个具有奇数和偶数的数组,并通过TASK操作显示为自然数 提供方消费者方面

问题描述

考虑我们有2种异步方法

public async Task<int[]> GetoddNumbers() 
{
  return new int[] { 1,3,5,7,9 };
} 
public async Task<int[]> GetEvennumbers()
{
  return new int[] { 2,4,6,8,10 }; 
}

我想同时合并数组和显示1,2,9,10

我们如何通过C#中的TAP(基于任务的异步模式)来实现这一目标? 请提供宝贵的建议。

解决方法

您当前的实现不需要任何异步代码。

我想这只是一个简化的示例,所以我将它们视为异步方法。

static async Task Main(string[] args)
{
    var odds = await GetOddNumbers();
    var evens = await GetEvenNumbers();
    var numbers = (odds).Zip(evens)
      .SelectMany(tuple => new [] { tuple.First,tuple.Second });

    Console.ReadLine();
}
  1. 我们检索两个集合。
  2. 我们将Zip中的一个元素(odds)组合到evens中的另一个元素中。因此,我们将得到以下结构(元组数组):
[
  (1,2),(3,4),(5,6),(7,8),(9,10),]
  1. 为了使其平整,我们需要调用SelectMany。您可以通过First属性访问左侧的项目,而可以通过Second属性访问右侧的项目。
    3.1)如果只调用Select而不是SelectMany,那么最终将得到一个数组数组。
[
  [1,2],[3,4],[5,6],[7,8],[9,10],]

3.2)但是使用SelectMany我们将数组的数组展平为一个简单的数组。

[
  1,2,3,4,5,6,7,8,9,10
]

更新:OP添加了一项新要求(作为注释),要求应一次一异步地检索数据。

为了满足此要求,我们需要使用IAsyncEnumerable<T>。这使我们能够一次提供一个数据。

提供方

因此,我们不必返回Task<int[]>,而必须返回IAsyncEnumerable<int>GetOddNumbersGetEvenNumbers可以这样重写:

public static async IAsyncEnumerable<int> GetOddNumbers()
{
    var odds = new int[] { 1,9 };
    foreach (var odd in odds)
    {
        await Task.Delay(1000); //Whatever async method call
        yield return odd;
    }
}
public static async IAsyncEnumerable<int> GetEvenNumbers()
{
    var evens = new int[] { 2,10 };
    foreach (var even in evens)
    {
        await Task.Delay(1000); //Whatever async method call
        yield return even;
    }
}

消费者方面

我们可以利用C#8的新await foreach关键字。IAsyncEnumerable没有内置的Zip函数,因此我们需要使用自定义函数,例如:{{3 }}

有了这些Main方法将如下所示:

static async Task Main(string[] args)
{
    var toBeIterated = async_enumerable_dotnet.AsyncEnumerable.Zip(z => z,GetOddNumbers(),GetEvenNumbers());
    await foreach (int[] oddEvenPair in toBeIterated)
    {
        Console.WriteLine(oddEvenPair[0]);
        Console.WriteLine(oddEvenPair[1]);
    }

    Console.WriteLine("Finished");
    Console.ReadLine();
}

它将一次打印一对数据,然后在下一对数据之间等待一秒钟。

{1 sec wait}
1
2
{1 sec wait}
3
4
{1 sec wait}
5
6
{1 sec wait}
7
8
{1 sec wait}
9
10
Finished