다음을 통해 공유


Azure SDK 개체에 대한 스레드 안전성 및 클라이언트 수명 관리

이 문서는 Azure SDK를 사용할 때 스레드 안전 문제를 이해하는 데 도움이 됩니다. 또한 SDK 디자인이 클라이언트 수명 관리에 미치는 영향에 대해서도 설명합니다. Azure SDK 클라이언트 개체를 삭제할 필요가 없는 이유를 알아봅니다.

스레드 안전성

모든 Azure SDK 클라이언트 개체는 스레드로부터 안전하며 서로 독립적입니다. 이 설계를 통해 스레드 간에도 클라이언트 인스턴스를 다시 사용하는 것이 항상 안전합니다. 예를 들어 다음 코드는 여러 작업을 시작하지만 스레드로부터 안전합니다.

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

입력 모델이든 출력 모델이든 SDK 클라이언트에서 사용하는 모델 개체는 기본적으로 스레드로부터 안전하지 않습니다. 모델 개체와 관련된 대부분의 사용 사례는 단일 스레드만 사용합니다. 따라서 이러한 개체에 대해 동기화를 기본 동작으로 구현하는 데 드는 비용이 너무 높습니다. 다음 코드는 여러 스레드에서 모델에 액세스하면 정의되지 않은 동작이 발생할 수 있는 버그를 보여 줍니다.

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

다른 스레드에서 모델에 액세스하려면 사용자 고유의 동기화 코드를 구현해야 합니다. 다음은 그 예입니다.

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

클라이언트 수명

Azure SDK 클라이언트는 스레드로부터 안전하므로 지정된 생성자 매개 변수 집합에 대해 여러 SDK 클라이언트 개체를 생성할 이유가 없습니다. Azure SDK 클라이언트 개체를 한 번 생성된 단일 항목으로 처리합니다. 이 권장 사항은 일반적으로 앱의 IoC(Inversion of Control) 컨테이너에 Azure SDK 클라이언트 개체를 싱글톤으로 등록하여 구현됩니다. DI(종속성 주입)는 SDK 클라이언트 개체에 대한 참조를 가져오는 데 사용됩니다. 다음 예제에서는 단일 클라이언트 개체 등록을 보여줍니다.

var builder = Host.CreateApplicationBuilder(args);

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

builder.Services.AddSingleton(blobServiceClient);

Azure SDK를 사용하여 DI를 구현하는 방법에 대한 자세한 내용은 .NET용 Azure SDK를 사용한 종속성 주입을 참조하세요.

또는 SDK 클라이언트 인스턴스를 만들고 클라이언트가 필요한 메서드에 제공할 수 있습니다. 요점은 동일한 매개 변수를 사용하여 동일한 SDK 클라이언트 개체의 불필요한 인스턴스화를 방지하는 것입니다. 그것은 불필요하고 낭비입니다.

클라이언트는 삭제할 수 없습니다.

자주 나오는 두 가지 마지막 질문은 다음과 같습니다.

  • 사용이 완료되면 Azure SDK 클라이언트 개체를 삭제해야 하나요?
  • HTTP 기반 Azure SDK 클라이언트 개체를 삭제할 수 없는 이유는 무엇인가요?

내부적으로 모든 Azure SDK 클라이언트는 단일 공유 HttpClient 인스턴스를 사용합니다. 클라이언트는 적극적으로 해제해야 하는 다른 리소스를 만들지 않습니다. 공유 HttpClient 인스턴스는 전체 애플리케이션 수명 동안 유지됩니다.

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

Azure SDK 클라이언트 개체에 사용자 지정 인스턴스 HttpClient 를 제공할 수 있습니다. 이 경우 수명을 관리하고 HttpClient 적절한 시기에 적절하게 삭제할 책임이 있습니다.

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

인스턴스를 올바르게 관리하고 삭제하기 HttpClient 위한 추가 지침은 설명서에서 HttpClient 찾을 수 있습니다.

참고하십시오