

的版本 4 (V4) 适用于 .NET 的 AWS SDK 已经发布！

有关重大更改和迁移应用程序的信息，请参阅[迁移主题](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/net-dg-v4.html)。

 [https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/net-dg-v4.html](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/net-dg-v4.html)

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 在中使用分页结果 适用于 .NET 的 AWS SDK
<a name="paginators"></a>

某些 AWS 服务会收集和存储大量数据，您可以使用的 API 调用来检索这些数据 适用于 .NET 的 AWS SDK。如果您要检索的数据量变得太大，无法进行单个 API 调用，则可以通过使用*分页*将结果分成更易于管理的多个部分。

为了使您能够执行分页，开发工具包中许多服务客户端的请求和响应对象都提供了*延续令牌*（通常名为 `NextToken`）。其中一些服务客户端还提供了“分页工具”****。

分页工具使您能够避免延续令牌的开销，这可能涉及循环、状态变量、多个 API 调用等。使用分页工具时，您可以通过一行代码（`foreach` 循环的声明）从 AWS 服务中检索数据。如果需要多个 API 调用来检索数据，则分页工具会为您处理。

## 我在哪里可以找到分页工具？
<a name="paginators-find-them"></a>

并非所有服务都提供分页工具。确定服务是否为特定 API 提供分页工具的一种方法是在[适用于 .NET 的 AWS SDK API 参考](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/)中查看服务客户端类的定义。

例如，如果您检查该[AmazonCloudWatchLogsClient](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/CloudWatchLogs/TCloudWatchLogsClient.html)类的定义，就会看到一个`Paginators`属性。该属性为 Ama CloudWatch zon 日志提供了分页器。

## 分页工具能提供什么好处？
<a name="paginators-use-them"></a>

分页工具包含让您能够查看完整响应的属性。它们通常还包含一个或多个属性，使您可以访问响应中最有趣的部分，我们将其称为*关键结果*。

例如，在前`AmazonCloudWatchLogsClient`面提到的中，该`Paginator`对象包含一个`Responses`属性，其中包含来自 API 调用的完整[DescribeLogGroupsResponse](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/CloudWatchLogs/TDescribeLogGroupsResponse.html)对象。此 `Responses` 属性包含日志组集合等内容。

Paginator 对象还包含一个名为 `LogGroups` 的关键结果。此属性仅包含响应的日志组部分。有了这个关键结果，您就能在许多情况下减少和简化代码。

## 同步分页与异步分页
<a name="paginators-sync-async"></a>

分页工具提供同步和异步分页机制。.NET Framework 4.7.2（或更高版本）项目中提供同步分页。异步分页可在.NET 核心项目（.NET Core 3.1、.NET 5 等）中使用。

由于建议使用异步操作和 .NET Core，因此接下来的示例向您展示了异步分页。示例后面显示了有关如何使用同步分页和.NET Framework 4.7.2（或更高版本）执行相同任务的信息。[分页工具的其它注意事项](#paginators-additional)

## 示例
<a name="paginators-example"></a>

以下示例向您展示如何使用显示日志组列表。 适用于 .NET 的 AWS SDK 相比之下，该示例说明如何使用和不使用分页工具执行该操作。在查看完整代码（稍后所示）之前，请考虑以下片段。

**获取没有分页器的 CloudWatch 日志组**

```
      // Loop as many times as needed to get all the log groups
      var request = new DescribeLogGroupsRequest{Limit = LogGroupLimit};
      do
      {
        Console.WriteLine($"Getting up to {LogGroupLimit} log groups...");
        var response = await cwClient.DescribeLogGroupsAsync(request);
        foreach(var logGroup in response.LogGroups)
        {
          Console.WriteLine($"{logGroup.LogGroupName}");
        }
        request.NextToken = response.NextToken;
      } while(!string.IsNullOrEmpty(request.NextToken));
```

**使用分页器获取 CloudWatch 日志组**

```
      // No need to loop to get all the log groups--the SDK does it for us behind the scenes
      var paginatorForLogGroups =
        cwClient.Paginators.DescribeLogGroups(new DescribeLogGroupsRequest());
      await foreach(var logGroup in paginatorForLogGroups.LogGroups)
      {
        Console.WriteLine(logGroup.LogGroupName);
      }
```

这两个片段的结果完全相同，因此可以清楚地看到使用分页工具的好处。

**注意**  
在尝试构建和运行完整代码之前，请确保已[设置环境和项目](net-dg-config.md)。  
你可能还需要 [Microsoft.Bcl。 AsyncInterfaces](https://www.nuget.org/packages/Microsoft.Bcl.AsyncInterfaces/) NuGet 打包是因为异步分页器使用该`IAsyncEnumerable`接口。

### 完整代码
<a name="paginators-complete-code"></a>

本部分显示了本示例的相关参考和完整代码。

#### SDK 参考
<a name="w2aac13c13c23c19b5b1"></a>

NuGet 包裹：
+ [AWSSDK.CloudWatch](https://www.nuget.org/packages/AWSSDK.CloudWatch)

编程元素：
+ 命名空间 [Amazon。 CloudWatch](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/CloudWatch/NCloudWatch.html)

  班级 [AmazonCloudWatchLogsClient](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/CloudWatchLogs/TCloudWatchLogsClient.html)
+ 命名空间 [Amazon。 CloudWatchLogs.Model](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/CloudWatchLogs/NCloudWatchLogsModel.html)

  班级 [DescribeLogGroupsRequest](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/CloudWatchLogs/TDescribeLogGroupsRequest.html)

  班级 [DescribeLogGroupsResponse](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/CloudWatchLogs/TDescribeLogGroupsResponse.html)

  班级 [LogGroup](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/CloudWatchLogs/TLogGroup.html)

#### 完整代码
<a name="w2aac13c13c23c19b7b1"></a>

```
using System;
using System.Threading.Tasks;
using Amazon.CloudWatchLogs;
using Amazon.CloudWatchLogs.Model;

namespace CWGetLogGroups
{
  class Program
  {
    // A small limit for demonstration purposes
    private const int LogGroupLimit = 3;

    //
    // Main method
    static async Task Main(string[] args)
    {
      var cwClient = new AmazonCloudWatchLogsClient();
      await DisplayLogGroupsWithoutPaginators(cwClient);
      await DisplayLogGroupsWithPaginators(cwClient);
    }


    //
    // Method to get CloudWatch log groups without paginators
    private static async Task DisplayLogGroupsWithoutPaginators(IAmazonCloudWatchLogs cwClient)
    {
      Console.WriteLine("\nGetting list of CloudWatch log groups without using paginators...");
      Console.WriteLine("------------------------------------------------------------------");

      // Loop as many times as needed to get all the log groups
      var request = new DescribeLogGroupsRequest{Limit = LogGroupLimit};
      do
      {
        Console.WriteLine($"Getting up to {LogGroupLimit} log groups...");
        DescribeLogGroupsResponse response = await cwClient.DescribeLogGroupsAsync(request);
        foreach(LogGroup logGroup in response.LogGroups)
        {
          Console.WriteLine($"{logGroup.LogGroupName}");
        }
        request.NextToken = response.NextToken;
      } while(!string.IsNullOrEmpty(request.NextToken));
    }


    //
    // Method to get CloudWatch log groups by using paginators
    private static async Task DisplayLogGroupsWithPaginators(IAmazonCloudWatchLogs cwClient)
    {
      Console.WriteLine("\nGetting list of CloudWatch log groups by using paginators...");
      Console.WriteLine("-------------------------------------------------------------");

      // Access the key results; i.e., the log groups
      // No need to loop to get all the log groups--the SDK does it for us behind the scenes
      Console.WriteLine("\nFrom the key results...");
      Console.WriteLine("------------------------");
      IDescribeLogGroupsPaginator paginatorForLogGroups =
        cwClient.Paginators.DescribeLogGroups(new DescribeLogGroupsRequest());
      await foreach(LogGroup logGroup in paginatorForLogGroups.LogGroups)
      {
        Console.WriteLine(logGroup.LogGroupName);
      }

      // Access the full response
      // Create a new paginator, do NOT reuse the one from above
      Console.WriteLine("\nFrom the full response...");
      Console.WriteLine("--------------------------");
      IDescribeLogGroupsPaginator paginatorForResponses =
        cwClient.Paginators.DescribeLogGroups(new DescribeLogGroupsRequest());
      await foreach(DescribeLogGroupsResponse response in paginatorForResponses.Responses)
      {
        Console.WriteLine($"Content length: {response.ContentLength}");
        Console.WriteLine($"HTTP result: {response.HttpStatusCode}");
        Console.WriteLine($"Metadata: {response.ResponseMetadata}");
        Console.WriteLine("Log groups:");
        foreach(LogGroup logGroup in response.LogGroups) 
        {
          Console.WriteLine($"\t{logGroup.LogGroupName}");
        }
      }
    }
  }
}
```

## 分页工具的其它注意事项
<a name="paginators-additional"></a>
+ **分页工具不能多次使用**

  如果您需要在代码的多个位置显示特定 AWS 分页器的结果，则不得多次使用分页器对象。相反，每次需要时都要创建一个新的分页工具。这个概念如 `DisplayLogGroupsWithPaginators` 方法前面的示例代码中所示。
+ **同步分页**

  同步分页适用于.NET Framework 4.7.2（或更高版本）项目。

  要查看此内容，请创建一个.NET Framework 4.7.2（或更高版本）项目，然后将前面的代码复制到该项目中。然后只需将 `await` 关键字从两个 `foreach` 分页工具调用中移除，如以下示例所示。

  ```
  /*await*/ foreach(var logGroup in paginatorForLogGroups.LogGroups)
  {
    Console.WriteLine(logGroup.LogGroupName);
  }
  ```

  生成并运行该项目，以查看与异步分页相同的结果。