Lire en anglais

Partager via


Sécurité des threads et gestion de la durée de vie des clients pour les objets du SDK Azure

Cet article vous aide à comprendre les problèmes de sécurité des threads lors de l’utilisation du SDK Azure. Il décrit également l’impact de la conception du SDK sur la gestion de la durée de vie des clients. Vous allez découvrir pourquoi il n’est pas nécessaire de supprimer les objets clients du SDK Azure.

Sécurité des threads

Tous les objets clients du SDK Azure sont thread-safe et indépendants les uns des autres. Cette conception garantit que la réutilisation des instances clientes est toujours sécurisée, même entre threads. Par exemple, le code suivant lance plusieurs tâches, mais est thread-safe :

C#
var client = new SecretClient(
    new Uri("<secrets_endpoint>"), new DefaultAzureCredential());

foreach (var secretName in secretNames)
{
    // Using clients from parallel threads
    Task.Run(() => Console.WriteLine(client.GetSecret(secretName).Value));
}

Les objets de modèle utilisés par les clients SDK, qu’il s’agisse de modèles d’entrée ou de sortie, ne sont pas thread-safe par défaut. La plupart des cas d’usage impliquant des objets de modèle n’utilisent qu’un seul thread. Par conséquent, le coût d’implémentation de la synchronisation en tant que comportement par défaut est trop élevé pour ces objets. Le code suivant illustre un bogue dans lequel l’accès à un modèle à partir de plusieurs threads peut entraîner un comportement non défini :

C#
KeyVaultSecret newSecret = client.SetSecret("secret", "value");

foreach (var tag in tags)
{
    // Don't use model type from parallel threads
    Task.Run(() => newSecret.Properties.Tags[tag] = CalculateTagValue(tag));
}

client.UpdateSecretProperties(newSecret.Properties);

Pour accéder au modèle à partir de différents threads, vous devez implémenter votre propre code de synchronisation. Par exemple :

C#
KeyVaultSecret newSecret = client.SetSecret("secret", "value");

// Code omitted for brevity

foreach (var tag in tags)
{
    Task.Run(() =>
    {
        lock (newSecret)
        {
            newSecret.Properties.Tags[tag] = CalculateTagValue(tag);
        }
    );
}

client.UpdateSecretProperties(newSecret.Properties);

Durée de vie du client

Étant donné que les clients du SDK Azure sont thread-safe, il n’y a aucune raison de construire plusieurs objets clients de SDK pour un ensemble donné de paramètres de constructeur. Traitez les objets de client SDK Azure comme des singletons une fois construits. Cette recommandation est généralement implémentée en inscrivant des objets clients du SDK Azure en tant que singletons dans le conteneur Inversion of Control (IoC) de l’application. L’injection de dépendances (DI) est utilisée pour obtenir des références à l’objet de client SDK. L’exemple suivant montre une inscription d’objet client singleton :

C#
var builder = Host.CreateApplicationBuilder(args);

var endpoint = builder.Configuration["SecretsEndpoint"];
var blobServiceClient = new BlobServiceClient(
    new Uri(endpoint), new DefaultAzureCredential());

builder.Services.AddSingleton(blobServiceClient);

Pour plus d’informations sur l’implémentation de l’injection de dépendances à l’aide du kit SDK Azure, consultez Injection de dépendances avec le kit SDK Azure pour .NET.

Vous pouvez également créer une instance de client SDK et la fournir aux méthodes qui nécessitent un client. Le but est d’éviter les instanciations inutiles du même objet de client SDK avec les mêmes paramètres. C’est à la fois inutile et coûteux.

Les clients ne sont pas jetables

Les deux dernières questions qui reviennent souvent sont les suivantes :

  • Dois-je supprimer les objets de client SDK Azure lorsque j’ai fini de les utiliser ?
  • Pourquoi les objets de client SDK Azure basés sur HTTP ne sont-ils pas jetables ?

En interne, tous les clients du SDK Azure utilisent une seule instance HttpClient partagée. Les clients ne créent pas d’autres ressources qui doivent être libérées activement. L’instance partagée HttpClient persiste pendant toute la durée de vie de l’application.

C#
// Both clients reuse the shared HttpClient and don't need to be disposed
var blobClient = new BlobClient(new Uri(sasUri));
var blobClient2 = new BlobClient(new Uri(sasUri2));

Il est possible de fournir une instance personnalisée de HttpClient à un objet client du SDK Azure. Dans ce cas, vous devenez responsable de la gestion de la durée de vie de HttpClient et de sa suppression au moment adéquat.

C#
var httpClient = new HttpClient();

var clientOptions = new BlobClientOptions()
{
    Transport = new HttpClientTransport(httpClient)
};

// Both clients would use the HttpClient instance provided in clientOptions
var blobClient = new BlobClient(new Uri(sasUri), clientOptions);
var blobClient2 = new BlobClient(new Uri(sasUri2), clientOptions);

// Code omitted for brevity

// You're responsible for properly disposing httpClient some time later
httpClient.Dispose();

Vous trouverez des conseils supplémentaires sur la gestion et la suppression correctes des instances de HttpClient dans la documentation HttpClient.

Voir aussi