

 適用於 .NET 的 AWS SDK V3 已進入維護模式。

我們建議您遷移至 [適用於 .NET 的 AWS SDK V4](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/welcome.html)。如需如何遷移的其他詳細資訊和資訊，請參閱我們的[維護模式公告](https://aws.amazon.com/blogs/developer/aws-sdk-for-net-v3-maintenance-mode-announcement/)。

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 的功能 適用於 .NET 的 AWS SDK
<a name="net-dg-sdk-features"></a>

本節提供有關建立應用程式時 適用於 .NET 的 AWS SDK 可能需要考慮的 功能的資訊。

請確定您已先[設定專案](net-dg-config.md)。

如需為特定 AWS 服務開發軟體以及程式碼範例的資訊，請參閱 [使用 AWS 服務](working-with-aws-services.md)。如需其他程式碼範例，請參閱 [適用於 .NET 的 SDK 程式碼範例](csharp_code_examples.md)。

**Topics**
+ [非同步 API](sdk-net-async-api.md)
+ [重試和逾時](retries-timeouts.md)
+ [分頁程式](paginators.md)
+ [可觀測性](observability.md)
+ [其他工具](sdk-features-additional-tools.md)

# AWS 適用於 .NET 的非同步 APIs
<a name="sdk-net-async-api"></a>

 適用於 .NET 的 AWS SDK 使用*任務型非同步模式 (TAP)* 進行非同步實作。若要進一步了解 TAP，請參閱 https：//docs.microsoft.com 上的[任務型非同步模式 (TAP)](https://learn.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap)。

本主題概述如何在呼叫 AWS 服務用戶端時使用 TAP。

 適用於 .NET 的 AWS SDK API 中的非同步方法是根據 `Task`類別或 `Task<TResult>`類別的操作。如需這些類別的相關資訊，請參閱 docs.microsoft.com：//[https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task)[TResult](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1)。

當您的程式碼中呼叫這些 API 方法時，它們必須在使用 `async`關鍵字宣告的函數內呼叫，如下列範例所示。

```
static async Task Main(string[] args)
{
  ...
  // Call the function that contains the asynchronous API method.
  // Could also call the asynchronous API method directly from Main
  //  because Main is declared async
  var response = await ListBucketsAsync();
  Console.WriteLine($"Number of buckets: {response.Buckets.Count}");
  ...
}

// Async method to get a list of Amazon S3 buckets.
private static async Task<ListBucketsResponse> ListBucketsAsync()
{
  ...
  var response = await s3Client.ListBucketsAsync();
  return response;
}
```

如上述程式碼片段所示，`async`宣告的偏好範圍是 `Main`函數。設定此`async`範圍可確保對 AWS 服務用戶端的所有呼叫都必須是非同步的。如果您因為某些原因而無法宣告`Main`為非同步，您可以在 以外的函數上使用 `async`關鍵字，`Main`然後從該處呼叫 API 方法，如下列範例所示。

```
static void Main(string[] args)
{
  ...
  Task<ListBucketsResponse> response = ListBucketsAsync();
  Console.WriteLine($"Number of buckets: {response.Result.Buckets.Count}");
  ...
}

// Async method to get a list of Amazon S3 buckets.
private static async Task<ListBucketsResponse> ListBucketsAsync()
{
  ...
  var response = await s3Client.ListBucketsAsync();
  return response;
}
```

請注意，當您使用此模式`Main`時， 中需要的特殊`Task<>`語法。此外，您必須使用回應**`Result`**的成員來取得資料。

您可以在 [快速導覽](quick-start.md)區段 ([簡單的跨平台應用程式](quick-start-s3-1-cross.md) 和 [簡單的 Windows 型應用程式](quick-start-s3-1-winvs.md)) 和 中查看非同步呼叫 AWS 服務用戶端的完整範例[含指引的程式碼範例高階程式庫和架構](tutorials-examples.md)。

# 重試和逾時
<a name="retries-timeouts"></a>

 適用於 .NET 的 AWS SDK 可讓您設定對 AWS 服務的 HTTP 請求的重試次數和逾時值。如果重試和逾時的預設不適用於您的應用程式，您可以將它們兩者適時調整以配合您的需求，但請務必了解如此一來對應用程式產生的影響程度。

若要判斷哪些值用於重試和逾時，請考慮以下資訊：
+ 當網路連線降級或 AWS 服務無法連線時， 適用於 .NET 的 AWS SDK 和您的應用程式應如何回應？ 您是否希望快速呼叫失敗，還是應該呼叫保持重試？
+ 您的應用程式是使用者接觸應用程式，或是必須要有所回應的網站，或者是對延長的延遲時間具有更高容忍力的背景執行工作？
+ 應用程式是部署在低延遲的可靠網路上，還是部署在連線不可靠的遠端位置？

## 重試
<a name="retries"></a>

### 概觀
<a name="w2aac11c13c11b5"></a>

 適用於 .NET 的 AWS SDK 可以重試因伺服器端限流或連線中斷而失敗的請求。服務組態類別有兩個屬性，可用來指定服務用戶端的重試行為。服務組態類別會從 [適用於 .NET 的 AWS SDK API 參考](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/)的抽象 [Amazon.Runtime.ClientConfig](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TClientConfig.html) 類別繼承這些屬性：
+ `RetryMode` 指定三種重試模式之一，這些模式在 [Amazon.Runtime.RequestRetryMode](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TRequestRetryMode.html) 列舉中定義。

  您可以使用`AWS_RETRY_MODE`環境變數或共用組態檔案中的 *retry\$1mode* AWS 設定來控制應用程式的預設值。
+ `MaxErrorRetry` 指定服務用戶端層級允許的重試次數；軟體開發套件會在失敗和擲回例外狀況之前，以指定的次數重試操作。

  您可以使用`AWS_MAX_ATTEMPTS`環境變數或共用組態檔案中的 *max\$1attempts* AWS 設定來控制應用程式的預設值。

您可以在 [適用於 .NET 的 AWS SDK API 參考](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/)的摘要 [Amazon.Runtime.ClientConfig](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TClientConfig.html) 類別中找到這些屬性的詳細說明。根據預設， 的每個值都會`RetryMode`對應至 的特定值`MaxErrorRetry`，如下表所示。

|  |  |  | 
| --- |--- |--- |
| Legacy | 10 | 4 | 
| Standard | 10 | 2 | 
| Adaptive (experimental) | 10 | 2 | 

### Behavior (行為)
<a name="w2aac11c13c11b9"></a>

**您的應用程式啟動時**

當您的應用程式啟動時，軟體開發套件`MaxErrorRetry`會設定 `RetryMode`和 的預設值。除非您指定其他值，否則建立服務用戶端時會使用這些預設值。
+ 如果您的環境中未設定屬性，則 的預設值`RetryMode`會設定為 *Legacy*，而 的預設值`MaxErrorRetry`會設定為上表中的對應值。
+ 如果您的環境中已設定重試模式，則該值會用作 的預設值`RetryMode`。除非已在您的環境中設定最大錯誤的值 （接下來說明），否則 的預設值`MaxErrorRetry`會使用上表中的對應值進行設定。
+ 如果您的環境中已設定最大錯誤的值，則該值會用作 的預設值`MaxErrorRetry`。Amazon DynamoDB 是此規則的例外狀況； 的預設 DynamoDB 值一律`MaxErrorRetry`是上表中的值。

**當您的應用程式執行時**

建立服務用戶端時，您可以使用 `RetryMode`和 的預設值`MaxErrorRetry`，如先前所述，也可以指定其他值。若要指定其他值，請在建立服務用戶端時建立並包含服務組態物件，例如 [AmazonDynamoDBConfig](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/DynamoDBv2/TDynamoDBConfig.html) 或 [AmazonSQSConfig](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/SQS/TSQSConfig.html)。

建立服務用戶端之後，就無法變更這些值。

**考量**

重試時，請求的延遲會增加。您應該設定您的重試，依據您的應用程式限制總請求延遲和錯誤率而設定。

## 逾時
<a name="timeouts"></a>

 適用於 .NET 的 AWS SDK 可讓您在服務用戶端層級和每個方法呼叫設定請求逾時。設定逾時有兩種機制，涵蓋於後續章節：
+ 如果您使用的是[非同步呼叫](#timeouts-async)，則可以使用 方法的 `CancellationToken` 參數。
+ 如果您在 [.NET Framework 中使用同步呼叫](#timeouts-sync-framework)，則可以使用抽象 [Amazon.Runtime.ClientConfig](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TClientConfig.html) 類別的 `Timeout`和 `ReadWriteTimeout` 屬性。

### 針對逾時使用 `CancellationToken` 參數
<a name="timeouts-async"></a>

 適用於 .NET 的 AWS SDK 可讓您使用 `CancellationToken` 參數設定非同步呼叫的請求逾時。下列程式碼片段顯示範例。`System.Threading.Tasks.TaskCanceledException` 如果未在 10 秒內完成請求，程式碼會擲回。

```
string bucketName = "amzn-s3-demo-bucket";
string path = "pathToBucket";
using (var amazonS3Client = new AmazonS3Client(new AmazonS3Config()))
{
    // Cancel request after 10 seconds
    CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMilliseconds(10000));
    CancellationToken cancellationToken = cancellationTokenSource.Token;
    ListObjectsV2Request listRequestV2 = new()
    {
        BucketName = bucketName,
        Prefix = path,
    };

    ListObjectsV2Response listResponseV2 = await amazonS3Client.ListObjectsV2Async(listRequestV2, cancellationToken);
}
```

### 將 `Timeout`和 `ReadWriteTimeout` 屬性用於逾時
<a name="timeouts-sync-framework"></a>

**注意**  
`Timeout` 屬性不會影響非同步呼叫。如果您使用的是非同步呼叫，請[針對逾時使用 `CancellationToken` 參數](#timeouts-async)改為參閱 。

 適用於 .NET 的 AWS SDK 可讓您在服務用戶端層級設定請求逾時和通訊端讀取/寫入逾時值。這些值是在抽象 [Amazon.Runtime.ClientConfig](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TClientConfig.html) 類別的 `Timeout`和 `ReadWriteTimeout` 屬性中指定。這些值會做為 AWS 服務用戶端物件所建立 [HttpWebRequest](https://learn.microsoft.com/en-us/dotnet/api/system.net.httpwebrequest) 物件的 `Timeout`和 `ReadWriteTimeout` 屬性傳遞。在預設情況下，`Timeout` 值為 100 秒，`ReadWriteTimeout` 值為 300 秒。

當您的網路有高延遲或存在會造成操作重試的條件，使用長逾時值和次數高的重試，會導致某些開發套件的操作看起來沒有回應。

**注意**  
以可攜式類別程式庫 (PCL) 適用於 .NET 的 AWS SDK 為目標的 版本使用 [HttpClient](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient) 類別而非 `HttpWebRequest`類別，並且僅支援[逾時](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.timeout)屬性。

以下為例外狀況的預設逾時值。這些值時在您明確設定逾時值時會被覆寫。
+ `Timeout` 如果呼叫的方法上傳串流，例如 [AmazonS3Client.PutObjectAsync()](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/S3/MS3PutObjectAsyncPutObjectRequestCancellationToken.html)、[AmazonS3Client.UploadPartAsync()](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/S3/MS3UploadPartAsyncUploadPartRequestCancellationToken.html)、[AmazonGlacierClient.UploadArchiveAsync()](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Glacier/MGlacierUploadArchiveAsyncUploadArchiveRequestCancellationToken.html) 等，則 和 `ReadWriteTimeout`會設定為最大值。
+  適用於 .NET 的 AWS SDK 目標為 .NET Framework 設定的 版本`ReadWriteTimeout`，`Timeout`以及所有 [AmazonS3Client](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/S3/TS3Client.html) 和 [AmazonGlacierClient](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Glacier/TGlacierClient.html) 物件的最大值。
+  適用於 .NET 的 AWS SDK 將可攜式類別程式庫 (PCL) 和 .NET Core 設為所有 [AmazonS3Client](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/S3/TS3Client.html) 和 [AmazonGlacierClient](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Glacier/TGlacierClient.html) 物件`Timeout`最大值的 版本。

下列範例說明如何指定*標準*重試模式、最多 3 次重試、逾時 10 秒，以及讀取/寫入逾時 10 秒 （如適用）。[AmazonS3Client](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/S3/TS3Client.html) 建構函數會獲得 [AmazonS3Config](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/S3/TS3Config.html) 物件。

```
var s3Client = new AmazonS3Client(
  new AmazonS3Config
  {
    Timeout = TimeSpan.FromSeconds(10),
    // NOTE: The following property is obsolete for
    //       versions of the 適用於 .NET 的 AWS SDK that target .NET Core.
    ReadWriteTimeout = TimeSpan.FromSeconds(10),
    RetryMode = RequestRetryMode.Standard,
    MaxErrorRetry = 3
  });
```

# 分頁程式
<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/v3/apidocs/)中服務用戶端類別的定義。

例如，如果您檢查 [AmazonCloudWatchLogsClient](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CloudWatchLogs/TCloudWatchLogsClient.html) 類別的定義，您會看到 `Paginators` 屬性。這是為 Amazon CloudWatch Logs 提供分頁器的 屬性。

## 分頁程式提供什麼？
<a name="paginators-use-them"></a>

分頁程式包含可讓您查看完整回應的屬性。它們通常也包含一或多個屬性，可讓您存取最有趣的回應部分，我們將呼叫*關鍵結果*。

例如，在先前`AmazonCloudWatchLogsClient`提到的 中， `Paginator` 物件包含具有 API 呼叫中完整 [DescribeLogGroupsResponse](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CloudWatchLogs/TDescribeLogGroupsResponse.html) 物件的 `Responses` 屬性。此`Responses`屬性包含日誌群組的集合。

Paginator 物件也包含一個名為 的金鑰結果`LogGroups`。此屬性只會保留回應的日誌群組部分。擁有此金鑰結果可讓您在許多情況下減少和簡化程式碼。

## 同步與非同步分頁
<a name="paginators-sync-async"></a>

分頁程式提供同步和非同步的分頁機制。同步分頁可在 .NET Framework 4.7.2 （或更新版本） 專案中使用。.NET Core 專案 (.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>

本節顯示此範例的相關參考和完整程式碼。

#### 開發套件參考
<a name="w2aac11c15c23c19b5b1"></a>

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

程式設計元素：
+ 命名空間 [Amazon.CloudWatch](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CloudWatch/NCloudWatch.html)

  [AmazonCloudWatchLogsClient](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CloudWatchLogs/TCloudWatchLogsClient.html) 類別
+ 命名空間 [Amazon.CloudWatchLogs.Model](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CloudWatchLogs/NCloudWatchLogsModel.html)

  類別 [DescribeLogGroupsRequest](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CloudWatchLogs/TDescribeLogGroupsRequest.html)

  類別 [DescribeLogGroupsResponse](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CloudWatchLogs/TDescribeLogGroupsResponse.html)

  類別 [LogGroup](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CloudWatchLogs/TLogGroup.html)

#### 完整程式碼
<a name="w2aac11c15c23c19b7b1"></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 （或更新版本） 專案。
**警告**  
自 2024 年 8 月 15 日起， 適用於 .NET 的 AWS SDK 將終止對 .NET Framework 3.5 的支援，並將最低 .NET Framework 版本變更為 4.7.2。如需詳細資訊，請參閱部落格文章 [.NET Framework 3.5 和 4.5 目標的重要變更 適用於 .NET 的 AWS SDK](https://aws.amazon.com/blogs/developer/important-changes-coming-for-net-framework-3-5-and-4-5-targets-of-the-aws-sdk-for-net/)。

  若要查看，請建立 .NET Framework 4.7.2 （或更新版本） 專案，並將上述程式碼複製到其中。然後，只需從兩個`foreach`分頁器呼叫中移除`await`關鍵字，如下列範例所示。

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

  建置並執行專案，以查看與非同步分頁相同的結果。

# 可觀測性
<a name="observability"></a>

可觀測性是從系統發出的資料推斷系統目前狀態的程度。發出的資料通常稱為遙測。

 適用於 .NET 的 AWS SDK 可以提供兩種常見的遙測訊號、指標和追蹤以及記錄。您可以連接 [TelemetryProvider](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TTelemetryProvider.html)，將遙測資料傳送至可觀測性後端 （例如 [AWS X-Ray](https://docs.aws.amazon.com/xray/?icmpid=docs_homepage_devtools)或 [Amazon CloudWatch](https://docs.aws.amazon.com/cloudwatch/?icmpid=docs_homepage_mgmtgov))，然後對其採取行動。

根據預設， 軟體開發套件中會停用遙測訊號。本主題說明如何啟用和設定遙測輸出。

## 其他資源
<a name="observability-resources"></a>

如需啟用和使用可觀測性的詳細資訊，請參閱下列資源：
+ [OpenTelemetry](https://opentelemetry.io/)
+ 部落格文章[適用於 .NET 的 AWS SDK 使用 OpenTelemetry 在 中增強可觀測性](https://aws.amazon.com/blogs/developer/enhancing-observability-in-the-aws-sdk-for-net-with-opentelemetry/)。
+ 部落格文章[宣布 AWS .NET OpenTelemetry 程式庫的一般可用性](https://aws.amazon.com/blogs/dotnet/announcing-the-general-availability-of-aws-net-opentelemetry-libraries/)。
+ [OpenTelemetry 的匯出工具](https://opentelemetry.io/docs/languages/net/exporters/)
+ 如需 中可觀測性的範例 AWS Tools for PowerShell，請參閱《[Tools for PowerShell 使用者指南](https://docs.aws.amazon.com/powershell/latest/userguide/)》中的[可觀測性](https://docs.aws.amazon.com/powershell/latest/userguide/observability.html)。

## 設定 `TelemetryProvider`
<a name="observability-conf-telemetry-provider"></a>

您可以針對所有服務用戶端或個別用戶端`TelemetryProvider`，在應用程式中全域設定 ，如下列範例所示。[遙測供應商](observability-telemetry-providers.md) 本節包含遙測實作的相關資訊，包括 SDK 隨附的實作相關資訊。

### 設定預設全域遙測供應商
<a name="observability-conf-telemetry-provider-global"></a>

根據預設，每個服務用戶端都會嘗試使用全球可用的遙測提供者。如此一來，您可以設定一次提供者，所有用戶端都會使用它。在您建立任何服務用戶端之前，這應該只完成一次。

下列程式碼片段說明如何設定全域遙測供應商。然後，它會建立 Amazon S3 服務用戶端，並嘗試執行失敗的操作。程式碼會將追蹤和指標同時新增至應用程式。此程式碼使用以下 NuGet 套件： `OpenTelemetry.Exporter.Console`和 `OpenTelemetry.Instrumentation.AWS`。

**注意**  
如果您使用 AWS IAM Identity Center 進行身分驗證，請務必同時新增 `AWSSDK.SSO`和 `AWSSDK.SSOOIDC`。

```
using Amazon.S3;
using OpenTelemetry;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;

Sdk.CreateTracerProviderBuilder()
    .ConfigureResource(e => e.AddService("DemoOtel"))
    .AddAWSInstrumentation()
    .AddConsoleExporter()
    .Build();

Sdk.CreateMeterProviderBuilder()
    .ConfigureResource(e => e.AddService("DemoOtel"))
    .AddAWSInstrumentation()
    .AddConsoleExporter()
    .Build();

var s3Client = new AmazonS3Client();

try
{
    var listBucketsResponse = await s3Client.ListBucketsAsync();
    // Attempt to delete a bucket that doesn't exist.
    var deleteBucketResponse = await s3Client.DeleteBucketAsync("amzn-s3-demo-bucket");
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

Console.Read();
```

### 為特定服務用戶端設定遙測供應商
<a name="observability-conf-telemetry-provider-client"></a>

您可以使用特定的遙測提供者 （全域提供者除外） 來設定個別服務用戶端。若要這樣做，請使用服務用戶端建構函數的 Config 物件`TelemetryProvider`類別。例如，請參閱 [AmazonS3Config](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/S3/TS3Config.html) 並尋找 `TelemetryProvider` 屬性。如需自訂遙測實作的相關資訊[遙測供應商](observability-telemetry-providers.md)，請參閱 。

**Topics**
+ [其他資源](#observability-resources)
+ [設定 `TelemetryProvider`](#observability-conf-telemetry-provider)
+ [指標](observability-metrics.md)
+ [遙測供應商](observability-telemetry-providers.md)

# 指標
<a name="observability-metrics"></a>

下表列出 SDK 發出的遙測指標。[設定遙測提供者](observability.md#observability-conf-telemetry-provider)，讓指標可被觀察。


**發出哪些指標？**  

| 指標名稱 | 單位 | Type | Attributes | 描述 | 
| --- | --- | --- | --- | --- | 
| client.call.duration | s | 直方圖 | rpc.service、rpc.method | 整體通話持續時間 （包括傳送或接收請求和回應內文的重試次數和時間） | 
| client.uptime | s | 直方圖 | rpc.service | 自建立用戶端以來的時間 | 
| client.call.attempts | \$1attempt\$1 | MonotonicCounter | rpc.service、rpc.method | 個別操作的嘗試次數 | 
| client.call.errors | \$1error\$1 | MonotonicCounter | rpc.service、rpc.method、 exception.type | 操作的錯誤數目 | 
| client.call.attempt\$1duration | s | 直方圖 | rpc.service、rpc.method | 連線到服務、傳送請求，以及取回 HTTP 狀態碼和標頭所需的時間 （包括排入佇列等待傳送的時間） | 
| client.call.resolve\$1endpoint\$1duration | s | 直方圖 | rpc.service、rpc.method | 解析請求的端點 （端點解析程式，而非 DNS) 所需的時間 | 
| client.call.serialization\$1duration | s | 直方圖 | rpc.service、rpc.method | 序列化訊息內文所需的時間 | 
| client.call.deserialization\$1duration | s | 直方圖 | rpc.service、rpc.method | 還原序列化訊息內文所需的時間 | 
| client.call.auth.signing\$1duration | s | 直方圖 | rpc.service、rpc.method | 簽署請求所需的時間 | 
| client.call.auth.resolve\$1identity\$1duration | s | 直方圖 | rpc.service、rpc.method | 從身分提供者取得身分 （例如 AWS 憑證或承載字符） 所需的時間 | 
| client.http.bytes\$1sent | 根據 | MonotonicCounter | server.address | HTTP 用戶端傳送的位元組總數 | 
| client.http.bytes\$1received | 根據 | MonotonicCounter | server.address | HTTP 用戶端收到的位元組總數 | 

以下是欄描述：
+ **指標名稱** – 發出的指標名稱。
+ **單位** – 指標的度量單位。單位以區分[https://unitsofmeasure.org/ucum](https://unitsofmeasure.org/ucum)大小寫 ("c/s") 表示法表示。
+ **類型** – 用來擷取指標的 檢測類型。
+ **屬性** – 指標發出的一組屬性 （維度）。
+ **描述** – 指標測量內容的描述。

# 遙測供應商
<a name="observability-telemetry-providers"></a>

開發套件提供 [OpenTelemetry](https://opentelemetry.io/) 做為遙測提供者的實作，[下一節](observability-telemetry-providers-otel.md)將說明。

如果您有特定的遙測需求、已考慮遙測解決方案，或需要精細控制遙測資料的擷取和處理方式，您也可以實作自己的遙測供應商。

向 [TelemetryProvider](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TTelemetryProvider.html) 類別註冊您自己的實作。以下是如何註冊您自己的 `TracerProvider`和 的簡單範例`MeterProvider`。

```
using Amazon;
using Amazon.Runtime.Telemetry;
using Amazon.Runtime.Telemetry.Metrics;
using Amazon.Runtime.Telemetry.Tracing;

public class CustomTracerProvider : TracerProvider
{
    // Implement custom tracing logic here
}
public class CustomMeterProvider : MeterProvider
{
    // Implement custom metrics logic here
}

// Register custom implementations
AWSConfigs.TelemetryProvider.RegisterTracerProvider(new CustomTracerProvider());
AWSConfigs.TelemetryProvider.RegisterMeterProvider(new CustomMeterProvider());
```

**Topics**
+ [OpenTelemetry](observability-telemetry-providers-otel.md)

# 設定 OpenTelemetry 型遙測供應商
<a name="observability-telemetry-providers-otel"></a>

 適用於 .NET 的 AWS SDK 包含 OpenTelemetry 型遙測供應商的實作。如需如何將此提供者設定為全域遙測提供者的詳細資訊，請參閱 [設定 `TelemetryProvider`](observability.md#observability-conf-telemetry-provider)。若要使用此遙測提供者，您需要專案中的下列資源：
+ [OpenTelemetry.Instrumentation.AWS](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AWS) NuGet 套件。
+ 遙測匯出工具，例如 OTLP 或 主控台。如需詳細資訊，請參閱 OpenTelemetry 文件中的[匯出工具](https://opentelemetry.io/docs/languages/net/exporters/)。

開發套件隨附的 OpenTelemetry 實作可設定為減少 HTTPS 請求、登入資料和壓縮的追蹤量。若要這樣做，請將 `SuppressDownstreamInstrumentation`選項設定為 `true`，如下所示：

```
Sdk.CreateTracerProviderBuilder()
    .ConfigureResource(e => e.AddService("DemoOtel"))
    .AddAWSInstrumentation(options => options.SuppressDownstreamInstrumentation = true)
    .AddConsoleExporter()
    .Build();
```

如需此提供者的其他資訊，請參閱 中的部落格文章[適用於 .NET 的 AWS SDK 使用 OpenTelemetry 增強可觀測性](https://aws.amazon.com/blogs/developer/enhancing-observability-in-the-aws-sdk-for-net-with-opentelemetry/)。

# 其他工具
<a name="sdk-features-additional-tools"></a>

以下是一些額外的工具，您可以用來簡化開發、部署和維護 .NET 應用程式的工作。

## AWS 部署工具
<a name="sdk-features-deployment-tool"></a>

在開發機器上開發雲端原生 .NET Core 應用程式之後，您可以使用適用於 .NET CLI 的 AWS 部署工具，更輕鬆地將應用程式部署到 AWS。

如需詳細資訊，請參閱[將應用程式部署到 AWS](deploying.md)。

## AWS 適用於 .NET 的訊息處理架構
<a name="sdk-features-msg-proc"></a>

如果您使用的是 Amazon SQS、Amazon SNS 或 Amazon EventBridge 等服務，您可以利用適用於 .NET AWS 的訊息處理架構。如需詳細資訊，請參閱[AWS 適用於 .NET 的訊息處理架構](msg-proc-fw.md)。

## 與 .NET Acover 整合
<a name="sdk-features-aspire-integrations"></a>

您可以利用與 .NET Aspire 整合的優勢來改善內部開發迴圈。如需詳細資訊，請參閱[在 中 AWS 與 .NET ACache 整合 適用於 .NET 的 AWS SDK](aspire-integrations.md)。