Leer en inglés

Compartir a través de


Seguridad para subprocesos y administración de la duración del cliente para objetos de Azure SDK

Este artículo le ayuda a comprender los problemas de seguridad para subprocesos al usar Azure SDK. También se describe cómo afecta el diseño del SDK a la administración de la duración del cliente. Aprenderá por qué no es necesario eliminar objetos de cliente de Azure SDK.

Seguridad para subprocesos

Todos los objetos de cliente de Azure SDK son seguros para subprocesos e independientes entre sí. Este diseño garantiza que la reutilización de instancias de cliente sea siempre segura, incluso entre subprocesos. Por ejemplo, el código siguiente inicia varias tareas, pero es seguro para subprocesos:

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

Los objetos de modelo usados por los clientes del SDK, ya sean modelos de entrada o salida, no son seguros para subprocesos de forma predeterminada. En la mayoría de los casos de uso que implican objetos de modelo solo se usa un único subproceso. Por lo tanto, el costo de implementar la sincronización como comportamiento predeterminado es demasiado alto para estos objetos. El código siguiente muestra un error en el que el acceso a un modelo desde varios subprocesos podría provocar un comportamiento indefinido:

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

Para acceder al modelo desde subprocesos diferentes, debe implementar su propio código de sincronización. Por ejemplo:

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

Duración del cliente

Dado que los clientes de Azure SDK son seguros para subprocesos, no hay ninguna razón para construir varios objetos de cliente del SDK para un conjunto determinado de parámetros del constructor. Trate los objetos de cliente de Azure SDK como singletons una vez construidos. Esta recomendación se implementa normalmente mediante el registro de objetos de cliente de Azure SDK como singletons en el contenedor Inversión de control (IoC) de la aplicación. La inserción de dependencias (DI) se usa para obtener referencias al objeto de cliente del SDK. En el ejemplo siguiente se muestra un registro de objetos de cliente 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);

Para más información sobre cómo implementar la inserción de dependencias con Azure SDK, consulte Inserción de dependencias con Azure SDK para .NET.

Como alternativa, puede crear una instancia de cliente del SDK y proporcionarla a aquellos métodos que requieran un cliente. El caso es evitar la creación de instancias innecesaria del mismo objeto de cliente del SDK con los mismos parámetros. Es innecesario y un despilfarro.

Los clientes no son descartables

Dos preguntas finales que suelen aparecer son:

  • ¿Debo eliminar los objetos de cliente de Azure SDK cuando termine de usarlos?
  • ¿Por qué no se pueden eliminar los objetos de cliente de Azure SDK basados en HTTP?

Internamente, todos los clientes de Azure SDK usan una única instancia de HttpClient compartida. Los clientes no crean ningún otro recurso que deba liberarse activamente. La instancia de HttpClient compartida se conserva a lo largo de toda la duración de la aplicación.

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

Es posible proporcionar una instancia personalizada de HttpClient a un objeto de cliente de Azure SDK. En este caso, usted pasa a ser responsable de administrar la duración de HttpClient y eliminarla correctamente en el momento adecuado.

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();

Puede encontrar más instrucciones para administrar y eliminar instancias de HttpClient correctamente en la documentación HttpClient.

Vea también