

La AWS SDK pour .NET V3 est passée en mode maintenance.

Nous vous recommandons de migrer vers la version [AWS SDK pour .NET V4](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/welcome.html). Pour plus de détails et d'informations sur la façon de migrer, veuillez consulter notre [annonce relative au mode de maintenance](https://aws.amazon.com/blogs/developer/aws-sdk-for-net-v3-maintenance-mode-announcement/).

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Caractéristiques du AWS SDK pour .NET
<a name="net-dg-sdk-features"></a>

Cette section fournit des informations sur les fonctionnalités AWS SDK pour .NET que vous devrez peut-être prendre en compte lors de la création de vos applications.

Assurez-vous d'avoir d'abord [configuré votre projet](net-dg-config.md).

Pour plus d'informations sur le développement de logiciels pour des AWS services spécifiques ainsi que des exemples de code, consultez[Travaillez avec les AWS services](working-with-aws-services.md). Pour des exemples de code supplémentaires, voir[SDK pour .NET exemples de code](csharp_code_examples.md).

**Topics**
+ [Asynchrone APIs](sdk-net-async-api.md)
+ [Rétentatives et délais d'attente](retries-timeouts.md)
+ [Paginateurs](paginators.md)
+ [Observabilité](observability.md)
+ [Outils supplémentaires](sdk-features-additional-tools.md)

# AWS asynchrone APIs pour .NET
<a name="sdk-net-async-api"></a>

 AWS SDK pour .NET utilise le *modèle asynchrone basé sur les tâches (TAP) pour son implémentation asynchrone*. Pour en savoir plus sur le TAP, consultez la section [Modèle asynchrone basé sur les tâches (TAP)](https://learn.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap) sur docs.microsoft.com.

Cette rubrique vous donne un aperçu de la façon d'utiliser le TAP dans vos appels aux clients AWS du service.

Les méthodes asynchrones de l' AWS SDK pour .NET API sont des opérations basées sur la `Task` classe ou la `Task<TResult>` classe. [Consultez le site docs.microsoft.com pour obtenir des informations sur ces classes : [classe Task, Task< > class](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)

Lorsque ces méthodes d'API sont appelées dans votre code, elles doivent être appelées dans une fonction déclarée avec le `async` mot clé, comme indiqué dans l'exemple suivant.

```
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;
}
```

Comme indiqué dans l'extrait de code précédent, la portée préférée de la `async` déclaration est la `Main` fonction. La définition de cette `async` étendue garantit que tous les appels aux clients du AWS service doivent être asynchrones. Si vous ne pouvez pas `Main` déclarer que vous êtes asynchrone pour une raison quelconque, vous pouvez utiliser le `async` mot clé sur des fonctions autres que `Main` puis appeler les méthodes de l'API à partir de là, comme indiqué dans l'exemple suivant. 

```
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;
}
```

Notez la `Task<>` syntaxe spéciale requise `Main` lorsque vous utilisez ce modèle. En outre, vous devez utiliser le **`Result`**membre de la réponse pour obtenir les données.

Vous pouvez voir des exemples complets d'appels asynchrones à des clients AWS de service dans la [Faites une visite rapide](quick-start.md) section ([Application multiplateforme simple](quick-start-s3-1-cross.md)et[Application simple basée sur Windows](quick-start-s3-1-winvs.md)) et dans. [Exemples de code avec conseilsBibliothèques et frameworks de haut niveau](tutorials-examples.md)

# Rétentatives et délais d'attente
<a name="retries-timeouts"></a>

Vous AWS SDK pour .NET permet de configurer le nombre de tentatives et les valeurs de délai d'expiration pour les requêtes HTTP adressées aux AWS services. Si les valeurs par défaut concernant les nouvelles tentatives et les délais d'expiration ne conviennent pas à votre application, vous pouvez les ajuster selon vos besoins spécifiques, mais il est important de comprendre en quoi le comportement de votre application en sera affecté.

Pour déterminer quelles valeurs utiliser pour les nouvelles tentatives et les délais d'expiration, prenez en compte les éléments suivants :
+ Comment l'application AWS SDK pour .NET et votre application doivent-elles réagir lorsque la connectivité réseau se dégrade ou qu'un AWS service est inaccessible ? Souhaitez-vous que l'appel échoue rapidement ou est-il indiqué que l'appel continue de faire l'objet de nouvelles tentatives en votre nom ?
+ Votre application est-elle une application ou un site web orienté vers l'utilisateur qui doit être réactive ou s'agit-il d'une tâche de traitement en arrière plan qui tolère davantage les latences accrues ?
+ L'application est-elle déployée sur un réseau fiable à faible latence ou est-elle déployée sur un site distant avec une connectivité peu fiable ?

## Nouvelles tentatives
<a name="retries"></a>

### Présentation de
<a name="w2aac11c13c11b5"></a>

Ils AWS SDK pour .NET peuvent réessayer les demandes qui échouent en raison d'un ralentissement côté serveur ou d'une interruption de connexion. Il existe deux propriétés des classes de configuration de service que vous pouvez utiliser pour spécifier le comportement d'un client de service en cas de nouvelle tentative. Les classes de configuration de service héritent de ces propriétés de l'abstrait [Amazon.Runtime. ClientConfig](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TClientConfig.html)classe de l'[AWS SDK pour .NET API Reference](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/) :
+ `RetryMode`spécifie l'un des trois modes de nouvelle tentative définis dans [Amazon.Runtime. RequestRetryMode](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TRequestRetryMode.html)énumération.

  La valeur par défaut de votre application peut être contrôlée à l'aide de la variable d'`AWS_RETRY_MODE`environnement ou du paramètre *retry\$1mode* dans le fichier de configuration partagé AWS .
+ `MaxErrorRetry`indique le nombre de tentatives autorisées au niveau du client de service ; le SDK réessaie l'opération le nombre de fois spécifié avant d'échouer et de lancer une exception.

  La valeur par défaut de votre application peut être contrôlée à l'aide de la variable d'`AWS_MAX_ATTEMPTS`environnement ou du paramètre *max\$1attempts* du fichier de AWS configuration partagé.

Les descriptions détaillées de ces propriétés se trouvent dans le résumé [Amazon.Runtime. ClientConfig](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TClientConfig.html)classe de l'[AWS SDK pour .NET API Reference](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/). Chaque valeur de `RetryMode` correspond par défaut à une valeur particulière de`MaxErrorRetry`, comme indiqué dans le tableau suivant.

|  |  |  | 
| --- |--- |--- |
| Héritée | 10 | 4 | 
| Standard | 10 | 2 | 
| Adaptatif (expérimental) | 10 | 2 | 

### Comportement
<a name="w2aac11c13c11b9"></a>

**Quand votre candidature démarre**

Lorsque votre application démarre, les valeurs par défaut pour `RetryMode` et `MaxErrorRetry` sont configurées par le SDK. Ces valeurs par défaut sont utilisées lorsque vous créez un client de service, sauf si vous spécifiez d'autres valeurs.
+ Si les propriétés ne sont pas définies dans votre environnement, la valeur par défaut `RetryMode` est configurée comme *Legacy* et la valeur par défaut pour `MaxErrorRetry` est configurée avec la valeur correspondante du tableau précédent.
+ Si le mode de nouvelle tentative a été défini dans votre environnement, cette valeur est utilisée par défaut pour`RetryMode`. La valeur par défaut pour `MaxErrorRetry` est configurée avec la valeur correspondante du tableau précédent, sauf si la valeur pour les erreurs maximales a également été définie dans votre environnement (décrit ci-dessous).
+ Si la valeur du maximum d'erreurs a été définie dans votre environnement, cette valeur est utilisée par défaut pour`MaxErrorRetry`. Amazon DynamoDB fait exception à cette règle ; la valeur DynamoDB par défaut `MaxErrorRetry` pour est toujours celle du tableau précédent.

**Pendant l'exécution de votre application**

Lorsque vous créez un client de service, vous pouvez utiliser les valeurs par défaut pour `RetryMode` et`MaxErrorRetry`, comme décrit précédemment, ou vous pouvez spécifier d'autres valeurs. Pour spécifier d'autres valeurs, créez et incluez un objet de configuration de service tel qu'[AmazonDynamoDBConfig](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/DynamoDBv2/TDynamoDBConfig.html)[Amazon SQSConfig](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/SQS/TSQSConfig.html) lorsque vous créez le client de service.

Ces valeurs ne peuvent pas être modifiées pour un client de service après sa création.

**Considérations**

Lorsqu'une nouvelle tentative a lieu, la latence de votre demande augmente. Vous devez configurer les nouvelles tentatives en fonction des limites de votre application en termes de latence totale des demandes et de taux d'erreur.

## Délais
<a name="timeouts"></a>

Vous AWS SDK pour .NET permet de configurer les délais d'expiration des demandes au niveau du client de service et par appel de méthode. Il existe deux mécanismes pour configurer les délais d'expiration, qui sont abordés dans les sections suivantes :
+ Si vous utilisez des [appels asynchrones](#timeouts-async), vous pouvez utiliser le `CancellationToken` paramètre de la méthode.
+ Si vous utilisez des [appels synchrones dans .NET Framework](#timeouts-sync-framework), vous pouvez utiliser les `ReadWriteTimeout` propriétés `Timeout` et du fichier abstrait [Amazon.Runtime. ClientConfig](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TClientConfig.html)classe.

### Utilisation du `CancellationToken` paramètre pour les délais
<a name="timeouts-async"></a>

Vous AWS SDK pour .NET permet de configurer les délais d'expiration des demandes pour les appels asynchrones à l'aide du paramètre. `CancellationToken` L'extrait de code suivant montre un exemple. Le code est lancé `System.Threading.Tasks.TaskCanceledException` si la demande n'est pas terminée dans les 10 secondes.

```
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);
}
```

### Utilisation des `ReadWriteTimeout` propriétés `Timeout` et pour les délais d'expiration
<a name="timeouts-sync-framework"></a>

**Note**  
La `Timeout` propriété n'a aucun impact sur les appels asynchrones. Si vous utilisez des appels asynchrones, consultez [Utilisation du `CancellationToken` paramètre pour les délais](#timeouts-async) plutôt.

Vous AWS SDK pour .NET permet de configurer les valeurs du délai d'expiration de la demande et du read/write délai d'expiration du socket au niveau du client de service. Ces valeurs sont spécifiées dans les `ReadWriteTimeout` propriétés `Timeout` et du résumé [Amazon.Runtime. ClientConfig](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TClientConfig.html)classe. Ces valeurs sont transmises sous forme de `ReadWriteTimeout` propriétés `Timeout` et des [HttpWebRequest](https://learn.microsoft.com/en-us/dotnet/api/system.net.httpwebrequest)objets créés par l'objet client du AWS service. La valeur par défaut de `Timeout` est de 100 secondes et celle de `ReadWriteTimeout` est de 300 secondes.

Lorsque votre réseau présente une latence élevée ou qu'une opération fait l'objet d'une nouvelle tentative du fait de certaines conditions, un long délai d'expiration et un nombre élevé de nouvelles tentatives peuvent donner l'impression que certaines opérations du kit SDK ne répondent pas.

**Note**  
La version AWS SDK pour .NET qui cible la bibliothèque de classes portable (PCL) utilise la [HttpClient](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient)classe au lieu de la `HttpWebRequest` classe et ne prend en charge que la propriété [Timeout](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.timeout).

Vous trouverez ci-dessous les exceptions aux valeurs de délai d'expiration par défaut. Ces valeurs sont remplacées lorsque vous définissez explicitement les valeurs de délai d'expiration.
+ `Timeout`et `ReadWriteTimeout` sont définis sur les valeurs maximales si la méthode appelée télécharge un flux, tel que [AmazonS3Client. PutObjectAsync()](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/S3/MS3PutObjectAsyncPutObjectRequestCancellationToken.html), client [Amazon S3. 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), et ainsi de suite.
+ Les versions du .NET Framework cible AWS SDK pour .NET ont défini `Timeout` et `ReadWriteTimeout` atteint les valeurs maximales pour tous les clients et objets [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)
+ Les versions AWS SDK pour .NET qui ciblent la bibliothèque de classes portable (PCL) et .NET Core sont définies `Timeout` sur la valeur maximale pour tous les clients et objets [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)

L'exemple suivant vous montre comment définir le mode de nouvelle tentative *standard*, un maximum de 3 tentatives, un délai d'expiration de 10 secondes et un read/write délai d'expiration de 10 secondes (le cas échéant). [Le constructeur [AmazonS3Client](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/S3/TS3Client.html) reçoit un objet 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 AWS SDK pour .NET that target .NET Core.
    ReadWriteTimeout = TimeSpan.FromSeconds(10),
    RetryMode = RequestRetryMode.Standard,
    MaxErrorRetry = 3
  });
```

# Paginateurs
<a name="paginators"></a>

Certains AWS services collectent et stockent une grande quantité de données, que vous pouvez récupérer à l'aide des appels d'API du AWS SDK pour .NET. Si la quantité de données que vous souhaitez récupérer devient trop importante pour un seul appel d'API, vous pouvez diviser les résultats en éléments plus faciles à gérer grâce à la *pagination*. 

Pour vous permettre d'effectuer la pagination, les objets de demande et de réponse de nombreux clients de service du SDK fournissent un *jeton de continuation* (généralement nommé`NextToken`). Certains de ces clients de services fournissent également des **paginateurs**.

Les paginateurs vous permettent d'éviter la surcharge liée au jeton de continuation, qui peut impliquer des boucles, des variables d'état, plusieurs appels d'API, etc. Lorsque vous utilisez un paginateur, vous pouvez récupérer les données d'un AWS service par le biais d'une seule ligne de code, la déclaration d'une `foreach` boucle. Si plusieurs appels d'API sont nécessaires pour récupérer les données, le paginateur s'en charge pour vous.

## Où puis-je trouver des paginateurs ?
<a name="paginators-find-them"></a>

Tous les services ne proposent pas de paginateurs. L'un des moyens de déterminer si un service fournit un paginateur pour une API particulière consiste à examiner la définition d'une classe de client de service dans la référence d'[AWS SDK pour .NET API](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/).

Par exemple, si vous examinez la définition de la [AmazonCloudWatchLogsClient](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CloudWatchLogs/TCloudWatchLogsClient.html)classe, vous voyez une `Paginators` propriété. Il s'agit de la propriété qui fournit un paginateur pour Amazon CloudWatch Logs.

## Que m'apportent les paginateurs ?
<a name="paginators-use-them"></a>

Les paginateurs contiennent des propriétés qui vous permettent de voir les réponses complètes. Ils contiennent également généralement une ou plusieurs propriétés qui vous permettent d'accéder aux parties les plus intéressantes des réponses, que nous appellerons les *résultats clés*.

Par exemple, dans ce qui `AmazonCloudWatchLogsClient` a été mentionné précédemment, l'`Paginator`objet contient une `Responses` propriété contenant l'[DescribeLogGroupsResponse](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CloudWatchLogs/TDescribeLogGroupsResponse.html)objet complet issu de l'appel d'API. Cette `Responses` propriété contient, entre autres, un ensemble de groupes de journaux.

L'objet Paginator contient également un résultat clé nommé. `LogGroups` Cette propriété contient uniquement la partie de la réponse consacrée aux groupes de journaux. L'obtention de ce résultat clé vous permet de réduire et de simplifier votre code dans de nombreuses circonstances.

## Pagination synchrone ou asynchrone
<a name="paginators-sync-async"></a>

Les paginateurs fournissent des mécanismes de pagination synchrones et asynchrones. La pagination synchrone est disponible dans les projets .NET Framework 4.7.2 (ou version ultérieure). La pagination asynchrone est disponible dans les projets .NET Core (.NET Core 3.1, .NET 5, etc.).

Les opérations asynchrones et .NET Core étant recommandées, l'exemple suivant montre la pagination asynchrone. Les informations sur la façon d'effectuer les mêmes tâches à l'aide de la pagination synchrone et de .NET Framework 4.7.2 (ou version ultérieure) sont présentées après l'exemple dans. [Considérations supplémentaires pour les paginateurs](#paginators-additional)

## exemple
<a name="paginators-example"></a>

L'exemple suivant montre comment utiliser le pour AWS SDK pour .NET afficher une liste de groupes de journaux. Pour le contraste, l'exemple montre comment procéder avec et sans paginateurs. Avant d'examiner le code complet, présenté plus loin, considérez les extraits suivants.

**Obtenir des groupes de CloudWatch logs sans paginateurs**

```
      // 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));
```

**Obtenir des groupes de CloudWatch journaux à l'aide de paginateurs**

```
      // 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);
      }
```

Les résultats de ces deux extraits étant exactement les mêmes, l'avantage de l'utilisation de paginateurs est clairement visible.

**Note**  
Avant d'essayer de créer et d'exécuter le code complet, assurez-vous d'avoir [configuré votre environnement et votre projet](net-dg-config.md).  
Vous pourriez également avoir besoin du [Microsoft.Bcl. AsyncInterfaces](https://www.nuget.org/packages/Microsoft.Bcl.AsyncInterfaces/) NuGet package car les paginateurs asynchrones utilisent l'interface. `IAsyncEnumerable`

### Code complet
<a name="paginators-complete-code"></a>

Cette section présente les références pertinentes et le code complet de cet exemple.

#### Références du SDK
<a name="w2aac11c15c23c19b5b1"></a>

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

Éléments de programmation :
+ Espace de noms [Amazon. CloudWatch](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CloudWatch/NCloudWatch.html)

  Classe [AmazonCloudWatchLogsClient](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CloudWatchLogs/TCloudWatchLogsClient.html)
+ Espace de noms [Amazon. CloudWatchLogs.Modèle](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CloudWatchLogs/NCloudWatchLogsModel.html)

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

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

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

#### Code complet
<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}");
        }
      }
    }
  }
}
```

## Considérations supplémentaires pour les paginateurs
<a name="paginators-additional"></a>
+ **Les paginateurs ne peuvent pas être utilisés plus d'une fois**

  Si vous avez besoin des résultats d'un AWS paginateur spécifique à plusieurs endroits de votre code, vous ne devez pas utiliser un objet de pagination plusieurs fois. Créez plutôt un nouveau paginateur chaque fois que vous en avez besoin. Ce concept est illustré dans l'exemple de code précédent de la `DisplayLogGroupsWithPaginators` méthode.
+ **Pagination synchrone**

  La pagination synchrone est disponible pour les projets .NET Framework 4.7.2 (ou version ultérieure).
**Avertissement**  
À compter du 15 août 2024, le AWS SDK pour .NET support de .NET Framework 3.5 cessera et la version minimale de .NET Framework sera remplacée par 4.7.2. Pour plus d'informations, consultez le billet de blog [Changements importants à venir pour les cibles .NET Framework 3.5 et 4.5 du AWS SDK pour .NET](https://aws.amazon.com/blogs/developer/important-changes-coming-for-net-framework-3-5-and-4-5-targets-of-the-aws-sdk-for-net/).

  Pour ce faire, créez un projet .NET Framework 4.7.2 (ou version ultérieure) et copiez-y le code précédent. Il suffit ensuite de supprimer le `await` mot clé des deux appels de `foreach` pagination, comme indiqué dans l'exemple suivant.

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

  Créez et exécutez le projet pour obtenir les mêmes résultats que ceux obtenus avec la pagination asynchrone.

# Observabilité
<a name="observability"></a>

L'observabilité est la mesure dans laquelle l'état actuel d'un système peut être déduit des données qu'il émet. Les données émises sont communément appelées télémétrie.

Ils AWS SDK pour .NET peuvent fournir deux signaux de télémétrie courants, les métriques et les traces, ainsi que la journalisation. Vous pouvez connecter un [TelemetryProvider](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TTelemetryProvider.html)pour envoyer des données de télémétrie à un backend d'observabilité (tel que [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)), puis agir en conséquence.

Par défaut, les signaux de télémétrie sont désactivés dans le SDK. Cette rubrique explique comment activer et configurer la sortie de télémétrie.

## Ressources supplémentaires
<a name="observability-resources"></a>

Pour plus d'informations sur l'activation et l'utilisation de l'observabilité, consultez les ressources suivantes :
+ [OpenTelemetry](https://opentelemetry.io/)
+ Le billet de blog [Enhancing Observability in the AWS SDK pour .NET with OpenTelemetry](https://aws.amazon.com/blogs/developer/enhancing-observability-in-the-aws-sdk-for-net-with-opentelemetry/).
+ Le billet de blog [annonçant la disponibilité générale des OpenTelemetry bibliothèques AWS .NET](https://aws.amazon.com/blogs/dotnet/announcing-the-general-availability-of-aws-net-opentelemetry-libraries/).
+ [Exportateurs pour OpenTelemetry](https://opentelemetry.io/docs/languages/net/exporters/)
+ Pour des exemples d'observabilité dans le Outils AWS pour PowerShell, voir [Observabilité](https://docs.aws.amazon.com/powershell/latest/userguide/observability.html) dans le guide [ PowerShell d'utilisation des outils](https://docs.aws.amazon.com/powershell/latest/userguide/).

## Configurez un `TelemetryProvider`
<a name="observability-conf-telemetry-provider"></a>

Vous pouvez configurer un `TelemetryProvider` dans votre application globalement pour tous les clients de service ou pour des clients individuels, comme indiqué dans les exemples suivants. La [Fournisseurs de services de télémétrie](observability-telemetry-providers.md) section contient des informations sur les implémentations de télémétrie, notamment des informations sur les implémentations fournies avec le SDK.

### Configuration du fournisseur de télémétrie global par défaut
<a name="observability-conf-telemetry-provider-global"></a>

Par défaut, chaque client de service tente d'utiliser le fournisseur de télémétrie disponible dans le monde entier. De cette façon, vous pouvez définir le fournisseur une seule fois, et tous les clients l'utiliseront. Cela ne doit être fait qu'une seule fois, avant de créer des clients de service.

L'extrait de code suivant explique comment définir le fournisseur de télémétrie global. Il crée ensuite un client de service Amazon S3 et tente d'effectuer une opération qui échoue. Le code ajoute à la fois le suivi et les métriques à l'application. Ce code utilise les NuGet packages suivants : `OpenTelemetry.Exporter.Console` et`OpenTelemetry.Instrumentation.AWS`.

**Note**  
Si vous l'utilisez AWS IAM Identity Center pour l'authentification, veillez également à ajouter `AWSSDK.SSO` et`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();
```

### Configuration d'un fournisseur de télémétrie pour un client de service spécifique
<a name="observability-conf-telemetry-provider-client"></a>

Vous pouvez configurer un client de service individuel auprès d'un fournisseur de télémétrie spécifique (autre que le fournisseur global). Pour ce faire, utilisez la `TelemetryProvider` classe de l'objet Config d'un constructeur de client de service. Par exemple, consultez [AmazonS3Config](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/S3/TS3Config.html) et recherchez la propriété. `TelemetryProvider` Consultez [Fournisseurs de services de télémétrie](observability-telemetry-providers.md) pour plus d'informations sur les implémentations de télémétrie personnalisées.

**Topics**
+ [Ressources supplémentaires](#observability-resources)
+ [Configurez un `TelemetryProvider`](#observability-conf-telemetry-provider)
+ [Métriques](observability-metrics.md)
+ [Fournisseurs de services de télémétrie](observability-telemetry-providers.md)

# Métriques
<a name="observability-metrics"></a>

Le tableau suivant répertorie les mesures de télémétrie émises par le SDK. [Configurez un fournisseur de télémétrie](observability.md#observability-conf-telemetry-provider) pour rendre les métriques observables.


**Quels indicateurs sont émis ?**  

| Nom de la métrique | Unités | Type | Attributs | Description | 
| --- | --- | --- | --- | --- | 
| durée de l'appel client | s | Histogramme | rpc.service, rpc.method | Durée totale de l'appel (y compris les nouvelles tentatives, le temps d'envoi ou de réception de la demande et le corps de réponse) | 
| client.uptime | s | Histogramme | rpc. service | Le temps écoulé depuis la création d'un client | 
| client.call.attempts | \$1tentative\$1 | MonotonicCounter | rpc.service, rpc.method | Le nombre de tentatives pour une opération individuelle | 
| client.call.errors | \$1erreur\$1 | MonotonicCounter | rpc.service, rpc.method, exception.type | Le nombre d'erreurs associées à une opération | 
| client.call.attempt duration | s | Histogramme | rpc.service, rpc.method | Le temps nécessaire pour se connecter au service, envoyer la demande et récupérer le code d'état HTTP et les en-têtes (y compris le temps passé dans la file d'attente avant d'être envoyé) | 
| client.call.resolve\$1endpoint\$1duration | s | Histogramme | rpc.service, rpc.method | Le temps nécessaire pour résoudre un point de terminaison (résolveur de point de terminaison, pas DNS) pour la demande | 
| client.call.serialization\$1duration | s | Histogramme | rpc.service, rpc.method | Le temps nécessaire pour sérialiser le corps d'un message | 
| client.call.deserialization\$1duration | s | Histogramme | rpc.service, rpc.method | Le temps nécessaire pour désérialiser le corps d'un message | 
| client.call.auth.signing\$1duration | s | Histogramme | rpc.service, rpc.method | Le temps nécessaire pour signer une demande | 
| client.call.auth.resolve\$1identity\$1duration | s | Histogramme | rpc.service, rpc.method | Le temps nécessaire pour acquérir une identité (telle qu'un AWS identifiant ou un jeton porteur) auprès d'un fournisseur d'identité | 
| client.http.bytes\$1sent | Par | MonotonicCounter | adresse du serveur | Le nombre total d'octets envoyés par le client HTTP | 
| client.http.octets\$1received | Par | MonotonicCounter | adresse du serveur | Le nombre total d'octets reçus par le client HTTP | 

Les descriptions des colonnes sont les suivantes :
+ **Nom de la métrique** : nom de la métrique émise.
+ **Unités** : unité de mesure de la métrique. Les unités sont données dans la notation [UCUM](https://unitsofmeasure.org/ucum) sensible aux majuscules et minuscules (« c/s »).
+ **Type** : type d'instrument utilisé pour capturer la métrique.
+ **Attributs** : ensemble d'attributs (dimensions) émis avec la métrique.
+ **Description** —Description de ce que mesure la métrique.

# Fournisseurs de services de télémétrie
<a name="observability-telemetry-providers"></a>

[Le SDK fournit une implémentation en [OpenTelemetry](https://opentelemetry.io/)tant que fournisseur de télémétrie, décrite dans la section suivante.](observability-telemetry-providers-otel.md)

Si vous avez des exigences spécifiques en matière de télémétrie, si vous avez déjà une solution de télémétrie en tête ou si vous avez besoin d'un contrôle précis sur la manière dont les données de télémétrie sont capturées et traitées, vous pouvez également mettre en œuvre votre propre fournisseur de télémétrie.

Enregistrez votre propre implémentation auprès de la [TelemetryProvider](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TTelemetryProvider.html)classe. Voici un exemple simple de la façon d'enregistrer votre propre `TracerProvider` et`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)

# Configuration du fournisseur OpenTelemetry de télémétrie basé
<a name="observability-telemetry-providers-otel"></a>

 AWS SDK pour .NET Cela inclut la mise en œuvre d'un fournisseur de télémétrie OpenTelemetry basé. Pour plus de détails sur la façon de définir ce fournisseur en tant que fournisseur de télémétrie mondial, consultez. [Configurez un `TelemetryProvider`](observability.md#observability-conf-telemetry-provider) Pour utiliser ce fournisseur de télémétrie, vous avez besoin des ressources suivantes dans votre projet :
+ Le package [OpenTelemetry.Instrumentation.aws.](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AWS) NuGet 
+ Un exportateur de télémétrie tel que OTLP ou Console. Pour plus d'informations, consultez la section [Exportateurs](https://opentelemetry.io/docs/languages/net/exporters/) dans la OpenTelemetry documentation.

L' OpenTelemetry implémentation incluse dans le SDK peut être configurée pour réduire le suivi des requêtes HTTPS, des informations d'identification et de la compression. Pour ce faire, définissez l'`SuppressDownstreamInstrumentation`option sur`true`, comme suit :

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

Pour plus d'informations sur ce fournisseur, consultez le billet de blog [Enhancing Observability in the AWS SDK pour .NET with OpenTelemetry](https://aws.amazon.com/blogs/developer/enhancing-observability-in-the-aws-sdk-for-net-with-opentelemetry/).

# Outils supplémentaires
<a name="sdk-features-additional-tools"></a>

Voici quelques outils supplémentaires que vous pouvez utiliser pour faciliter le développement, le déploiement et la maintenance de vos applications .NET.

## AWS Outil de déploiement
<a name="sdk-features-deployment-tool"></a>

Après avoir développé votre application .NET Core native pour le cloud sur une machine de développement, vous pouvez utiliser l'outil de AWS déploiement pour la CLI .NET afin de déployer plus facilement votre application sur AWS.

Pour de plus amples informations, veuillez consulter [Déployez des applications pour AWS](deploying.md).

## AWS Framework de traitement des messages pour .NET
<a name="sdk-features-msg-proc"></a>

Si vous utilisez des services tels qu'Amazon SQS, Amazon SNS ou EventBridge Amazon, vous pouvez peut-être tirer parti de l'infrastructure de traitement AWS des messages pour .NET. Pour de plus amples informations, veuillez consulter [AWS Framework de traitement des messages pour .NET](msg-proc-fw.md).

## Intégrations avec .NET Aspire
<a name="sdk-features-aspire-integrations"></a>

Vous pouvez tirer parti des intégrations avec .NET Aspire pour améliorer la boucle de développement interne. Pour de plus amples informations, veuillez consulter [Intégration AWS à .NET Aspire dans le AWS SDK pour .NET](aspire-integrations.md).