Szálbiztonság és ügyfélélettartam-kezelés Azure SDK-objektumokhoz
Ez a cikk segít megérteni a szálbiztonsági problémákat az Azure SDK használatakor. Azt is ismerteti, hogy az SDK tervezése hogyan befolyásolja az ügyfél élettartamának kezelését. Megtudhatja, miért szükségtelen az Azure SDK-ügyfélobjektumok megsemmisítése.
Menetbiztonság
Minden Azure SDK-ügyfélobjektum szálbiztos és független egymástól. Ez a kialakítás biztosítja, hogy az ügyfélpéldányok újrafelhasználása mindig biztonságos legyen, akár több szálon is. Az alábbi kód például több feladatot indít el, de a szál biztonságos:
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));
}
Az SDK-ügyfelek által használt modellobjektumok – akár bemeneti, akár kimeneti modellek – alapértelmezés szerint nem szálbiztosak. A modellobjektumokat érintő legtöbb használati eset csak egyetlen szálat használ. Ezért a szinkronizálás alapértelmezett viselkedésként való implementálásának költsége túl magas ezen objektumok esetében. Az alábbi kód bemutatja azt a hibát, amely miatt egy modell több szálból való elérése meghatározatlan viselkedést okozhat:
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);
A modell különböző szálakból való eléréséhez saját szinkronizálási kódot kell implementálnia. Példa:
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);
Ügyfél élettartama
Mivel az Azure SDK-ügyfelek szálbiztosak, nincs ok arra, hogy több SDK-ügyfélobjektumot hozzon létre egy adott konstruktorparaméter-készlethez. Az Azure SDK-ügyfélobjektumokat a létrehozás után egyetlentonként kezelheti. Ezt a javaslatot általában úgy implementáljuk, hogy az Azure SDK-ügyfélobjektumokat egyetlentonként regisztráljuk az alkalmazás Inversion of Control (IoC) tárolójában. A függőséginjektálás (DI) az SDK-ügyfélobjektumra mutató hivatkozások lekérésére szolgál. Az alábbi példa egy egytonos ügyfélobjektum-regisztrációt mutat be:
var builder = Host.CreateApplicationBuilder(args);
var endpoint = builder.Configuration["SecretsEndpoint"];
var blobServiceClient = new BlobServiceClient(
new Uri(endpoint), new DefaultAzureCredential());
builder.Services.AddSingleton(blobServiceClient);
A DI azure SDK-val való implementálásával kapcsolatos további információkért lásd : Függőséginjektálás az Azure SDK for .NET-hez.
Másik lehetőségként létrehozhat egy SDK-ügyfélpéldányt, és megadhatja azokat az ügyfeleket igénylő metódusokhoz. A lényeg, hogy elkerüljük ugyanannak az SDK-ügyfélobjektumnak az azonos paraméterekkel való szükségtelen példányosítását. Felesleges és pazarló is.
Az ügyfelek nem eldobhatóak
A gyakran felmerülő két utolsó kérdés a következő:
- El kell helyezni az Azure SDK-ügyfélobjektumokat, ha befejeztem a használatukat?
- Miért nem használhatóak a HTTP-alapú Azure SDK-ügyfélobjektumok?
Belsőleg minden Azure SDK-ügyfél egyetlen megosztott HttpClient
példányt használ. Az ügyfelek nem hoznak létre más erőforrásokat, amelyeket aktívan fel kell szabadítanának. A megosztott HttpClient
példány az alkalmazás teljes élettartama alatt megmarad.
// 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));
Egyéni példányt HttpClient
is megadhat egy Azure SDK-ügyfélobjektumnak. Ebben az esetben Ön lesz a felelős az HttpClient
élettartam kezeléséért és a megfelelő időben történő megfelelő ártalmatlanításáért.
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();
A példányok megfelelő kezelésével HttpClient
és eltávolításával kapcsolatos további útmutatás a HttpClient dokumentációban található.