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 用戶端所使用的模型物件 (無論是輸入還是輸出模型) 依預設都不具執行緒安全性。 涉及模型物件的使用案例大多都僅使用單一執行緒。 因此,以預設行為的形式為這些物件實作同步處理的成本太高。 下列程式碼說明從多個執行緒存取模型可能導致不明行為的錯誤 (bug):
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 用戶端物件視為單一物件。 這項建議常藉由將 Azure SDK 用戶端物件註冊為應用程式控制反轉 (IoC) 容器中的單一物件來實作。 相依性插入 (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 的詳細資訊,請參閱 Azure SDK for .NET 的相依性插入。
或者,您可以建立 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));
您可以將 HttpClient
的自訂執行個體提供給 Azure SDK 用戶端物件。 在此情況下,您須負責管理 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 文件。