閱讀英文

共用方式為


Azure SDK 物件的執行緒安全性和用戶端存留期管理

本文可協助您了解使用 Azure SDK 時的執行緒安全性問題。 此外也會討論 SDK 的設計對於用戶端存留期管理有何影響。 您將了解為何不需要處置 Azure SDK 用戶端物件。

執行緒安全

所有 Azure SDK 用戶端物件都是安全執行緒,且彼此獨立。 此設計可確保重複使用用戶端執行個體絕對安全無虞,即使跨執行緒亦然。 例如,下列程式碼會啟動多個工作,但保有執行緒安全性:

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

SDK 用戶端所使用的模型物件 (無論是輸入還是輸出模型) 依預設都不具執行緒安全性。 涉及模型物件的使用案例大多都僅使用單一執行緒。 因此,以預設行為的形式為這些物件實作同步處理的成本太高。 下列程式碼說明從多個執行緒存取模型可能導致不明行為的錯誤 (bug):

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

若要從不同的執行緒存取模型,您必須實作自己的同步處理常式程式碼。 例如:

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

用戶端存留期

由於 Azure SDK 用戶端具備執行緒安全性,因此沒有必要為一組指定的建構函式參數建構多個 SDK 用戶端物件。 建構之後,請將 Azure SDK 用戶端物件視為單一物件。 這項建議常藉由將 Azure SDK 用戶端物件註冊為應用程式控制反轉 (IoC) 容器中的單一物件來實作。 相依性插入 (DI) 可用來取得對 SDK 用戶端物件的參考。 下列範例說明單一用戶端物件註冊:

C#
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 的詳細資訊,請參閱 Azure SDK for .NET 的相依性插入

或者,您可以建立 SDK 用戶端執行個體,並將其提供給需要用戶端的方法。 這是為了避免對具有相同參數的相同 SDK 用戶端物件進行非必要的具現化。 此作業沒有必要,且會形成浪費。

用戶端無法處置

經常出現的兩個最終問題如下:

  • 當我用完 Azure SDK 用戶端物件時,是否需要處置這些物件?
  • HTTP 型 Azure SDK 用戶端物件為何無法處置?

在內部,所有 Azure SDK 用戶端都會使用一個共用的 HttpClient 執行個體。 用戶端不會建立任何其他需要主動釋放的資源。 共用 HttpClient 執行個體在整個應用程式存留期內會持續存在。

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

您可以將 HttpClient 的自訂執行個體提供給 Azure SDK 用戶端物件。 在此情況下,您須負責管理 HttpClient 存留期,並且適時予以適當處置。

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

如需正確管理和處置 HttpClient 執行個體的進一步指引,請參閱 HttpClient 文件。

另請參閱