Az Azure Queue Storage használatának első lépései a .NET-keretrendszerrel
Áttekintés
Az Azure Queue Storage felhőalapú üzenetküldést biztosít az alkalmazásösszetevők között. A méretezési alkalmazások tervezésekor az alkalmazásösszetevők gyakran egymástól függetlenek, így egymástól függetlenül skálázhatók. A Queue Storage aszinkron üzenetküldést biztosít az alkalmazásösszetevők között, függetlenül attól, hogy a felhőben, az asztalon, egy helyszíni kiszolgálón vagy egy mobileszközön futnak. A Queue Storage emellett támogatja az aszinkron feladatok kezelését és a folyamatfolyamatok kiépítését.
Az oktatóanyag ismertetése
Ez az oktatóanyag bemutatja, hogyan írhat .NET-kódot néhány gyakori forgatókönyvhöz az Azure Queue Storage használatával. Az ismertetett forgatókönyvek az üzenetsorok létrehozására és törlésére, valamint az üzenetsor üzeneteinek hozzáadására, olvasására és törlésére vonatkoznak.
Az oktatóanyag áttekintésének becsült ideje: 45 perc
Előfeltételek
Mi az a Queue Storage?
Az Azure Queue Storage szolgáltatás üzenetek nagy számban történő tárolására szolgál, amelyek HTTP- vagy HTTPS-kapcsolattal, hitelesített hívásokon keresztül a világon bárhonnan elérhetők. Egyetlen üzenetsor akár 64 KB méretű is lehet, és a tárfiók maximális kapacitásán belül több millió üzenetet tartalmazhat. Az üzenetsortárat gyakran használják az aszinkron feldolgozáshoz szükséges munka hátralékának létrehozására.
Üzenetsor-szolgáltatás fogalmai
Az Azure Queue szolgáltatás a következő összetevőket tartalmazza:
Tárfiók: Az Azure Storage-hoz való hozzáférés egy tárfiókon keresztül történik. További információ a tárfiókokról: Tárfiókok áttekintése.
Üzenetsor: Az üzenetsorok üzenetek készleteit tartalmazzák. Az összes üzenetnek üzenetsorban kell lennie. Vegye figyelembe, hogy az üzenetsor neve csak kisbetűket tartalmazhat. Az üzenetsorok elnevezésével kapcsolatos információkat lásd: Naming Queues and Metadata (Üzenetsorok és metaadatok elnevezése).
Üzenet: Egy legfeljebb 64 KB méretű, tetszőleges méretű üzenet. Egy üzenet legfeljebb 7 napig maradhat egy üzenetsorban. A 2017-07-29-es vagy újabb verzió esetén a maximális élettartam bármilyen pozitív szám lehet, vagy -1, amely azt jelzi, hogy az üzenet nem jár le. Ha ez a paraméter nincs megadva, az alapértelmezett élettartam hét nap.
URL-cím formátuma: Az üzenetsorok a következő URL-címformátummal címezhetők: http://
<storage account>
.queue.core.windows.net/<queue>
Az ábra egyik üzenetsora a következő URL-címmel érhető el:
http://myaccount.queue.core.windows.net/incoming-orders
Azure-tárfiók létrehozása
Az első Azure Storage-fiók létrehozásának legegyszerűbb módja a Azure Portal használata. További tudnivalókért lásd: Create a storage account (Tárfiók létrehozása).
Ezenkívül az Azure PowerShell, az Azure CLI, illetve a .NET-keretrendszerhez készült Azure Storage erőforrás-szolgáltató használatával is létrehozhat egy Azure-tárfiókot.
Ha jelenleg nem szeretne tárfiókot létrehozni az Azure-ban, az Azurite Storage Emulator használatával helyi környezetben is futtathatja és tesztelheti a kódot. További információ: Az Azurite emulátor használata helyi Azure Storage-fejlesztéshez.
A fejlesztési környezet beállítása
A következő lépésként állítsa be a fejlesztési környezetet a Visual Studióban, hogy kipróbálhassa az útmutatóban megadott példákat.
Windows-konzolalkalmazás projekt létrehozása
Hozzon létre egy új Windows-konzolalkalmazást a Visual Studióban. Az alábbi lépések bemutatják, hogyan hozhat létre konzolalkalmazást a Visual Studio 2019-ben. A lépések a Visual Studio más verziói esetén is hasonlók.
- Válassza azÚj> projekt fájlja>lehetőséget
- Platform>windowsos kiválasztása
- Válassza a Konzolalkalmazás (.NET-keretrendszer) lehetőséget
- Kattintson a Tovább gombra.
- A Projektnév mezőben adja meg az alkalmazás nevét
- Kattintson a Létrehozás elemre.
Az oktatóanyagban szereplő példák hozzáadhatók a konzolalkalmazás Program.cs
fájljában található Main()
metódushoz.
Az Azure Storage-ügyfélkódtárakat bármilyen típusú .NET-alkalmazásban használhatja, beleértve az Azure-felhőszolgáltatást vagy -webalkalmazást, valamint az asztali és mobilalkalmazásokat. Ebben az útmutatóban az egyszerűség kedvéért egy konzolalkalmazást használunk.
A szükséges csomagok telepítése a NuGettel
Az oktatóanyag elvégzéséhez az alábbi négy csomagra kell hivatkoznia a projektben:
- Azure.Core-kódtár a .NET-hez: Ez a csomag megosztott primitíveket, absztrakciókat és segítőket biztosít a modern .NET Azure SDK-ügyfélkódtárakhoz.
- Azure.Storage.Common ügyfélkódtár a .NET-hez: Ez a csomag a többi Azure Storage-ügyfélkódtár által megosztott infrastruktúrát biztosít.
- Azure.Storage.Queues ügyfélkódtár a .NET-hez: Ez a csomag lehetővé teszi az Azure Queue Storage használatát az ügyfél által esetleg elérhető üzenetek tárolásához.
- System.Configuration.ConfigurationManager könyvtár a .NET-hez: Ez a csomag hozzáférést biztosít az ügyfélalkalmazások konfigurációs fájljaihoz.
Ezeket a csomagokat a NuGet használatával szerezheti be. Kövesse az alábbi lépéseket:
- Kattintson a jobb gombbal a projektre a Megoldáskezelőben, és válassza a Manage NuGet Packages (NuGet-csomagok kezelése) lehetőséget.
- Válassza a Tallózás lehetőséget
- Keressen rá az online kifejezésre,
Azure.Storage.Queues
és válassza a Telepítés lehetőséget az Azure Storage-ügyfélkódtár és függőségeinek telepítéséhez. Ez az Azure.Storage.Common és az Azure.Core kódtárakat is telepíti, amelyek az üzenetsortár függőségei. - Keressen rá az online kifejezésre,
System.Configuration.ConfigurationManager
és válassza a Telepítés lehetőséget a Configuration Manager telepítéséhez.
A célkörnyezet meghatározása
Az útmutatóban lévő példákat kétféle környezetben futtathatja:
- A kódot futtathatja a felhőben, egy Azure Storage-fiókban.
- A kódot az Azurite storage emulátoron futtathatja. Az Azurite egy helyi környezet, amely egy Azure Storage-fiókot emulál a felhőben. Az Azurite ingyenes lehetőség a kód tesztelésére és hibakeresésére, amíg az alkalmazás fejlesztés alatt áll. Az emulátor egy jól ismert fiókot és kulcsot használ. További információ: Az Azurite emulátor használata helyi Azure Storage-fejlesztéshez és teszteléshez.
Megjegyzés
A Storage Emulator megcélzásával elkerülheti az Azure Storage-hoz kapcsolódó költségeket. Ha azonban úgy dönt, hogy egy Azure Storage-fiókot céloz meg a felhőben, az oktatóanyag végrehajtásának költségei elhanyagolhatók lesznek.
A tárolási kapcsolati sztring lekérése
A .NET-hez készült Azure Storage-ügyfélkódtárak tárolási kapcsolati sztring használatával támogatják a végpontok és hitelesítő adatok konfigurálását a tárolási szolgáltatások eléréséhez. További információ: Tárfiók hozzáférési kulcsainak kezelése.
A hitelesítési adatok másolása az Azure Portalról
A mintakódnak hitelesítenie kell a tárfiókhoz való hozzáférést. A hitelesítéshez meg kell adni az alkalmazás számára a tárfiók hitelesítő adatait egy kapcsolati sztring formájában. A tárfiók hitelesítő adatainak megtekintéséhez a következőt kell tennie:
Lépjen az Azure Portalra.
Keresse meg a Storage-fiókját.
A tárfiók áttekintésének Beállítások szakaszában válassza a Hozzáférési kulcsok elemet. Megjelennek a fiókhoz tartozó hozzáférési kulcsok, valamint az egyes kulcsokhoz tartozó kapcsolati sztringek.
Keresse meg a Kapcsolati sztring értéket a key1 területen, és kattintson a Másolás gombra a kapcsolati sztring másolásához. A kapcsolati sztring értékét hozzáadja egy környezeti változóhoz a következő lépés során.
A kapcsolati sztringekkel kapcsolatos további információkért lásd: Az Azure Storage kapcsolati sztringjének konfigurálása.
Megjegyzés
A tárfiók kulcsa hasonlít a tárfiók rendszergazdai jelszavához. Mindig ügyeljen a tárfiók kulcsának védelmére. Ne adja ki másoknak, ne kódolja fixen és ne mentse egy mások számára elérhető egyszerű szöveges fájlban. Ha azt gyanítja, hogy a kulcs biztonsága sérült, az Azure portál segítségével generálja újra.
A tárolási kapcsolati sztring egy konfigurációs fájlban tartható fenn a legjobban. A kapcsolati sztring konfigurálásához nyissa meg az app.config
fájlt a Visual Studio Megoldáskezelőjében. Adja hozzá az <appSettings>
itt látható elem tartalmát. Cserélje le connection-string
a elemet a tárfiókból a portálon másolt értékre:
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<appSettings>
<add key="StorageConnectionString" value="connection-string" />
</appSettings>
</configuration>
A konfiguráció beállítása például hasonló lesz a következőhöz:
<add key="StorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName=storagesample;AccountKey=GMuzNHjlB3S9itqZJHHCnRkrokLkcSyW7yK9BRbGp0ENePunLPwBgpxV1Z/pVo9zpem/2xSHXkMqTHHLcx8XRA==EndpointSuffix=core.windows.net" />
Az Azurite Storage Emulator megcélzásához használhat egy parancsikont, amely leképezi a jól ismert fióknevet és kulcsot. Ebben az esetben a kapcsolati sztring beállítása a következő:
<add key="StorageConnectionString" value="UseDevelopmentStorage=true" />
Hozzáadás irányelvekkel
Adja hozzá a következő using
irányelveket a Program.cs
fájl elejéhez:
using System; // Namespace for Console output
using System.Configuration; // Namespace for ConfigurationManager
using System.Threading.Tasks; // Namespace for Task
using Azure.Identity;
using Azure.Storage.Queues; // Namespace for Queue storage types
using Azure.Storage.Queues.Models; // Namespace for PeekedMessage
A Queue Storage-ügyfél létrehozása
Az QueueClient
osztály lehetővé teszi a Queue Storage-ban tárolt üzenetsorok lekérését. A szolgáltatásügyfél létrehozásának egyik módja:
//-------------------------------------------------
// Create the queue service client
//-------------------------------------------------
public void CreateQueueClient(string queueName)
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to create and manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
}
Tipp
Az osztály használatával QueueClient
küldött üzeneteknek olyan formátumban kell lenniük, amely UTF-8 kódolású XML-kérelemben szerepelhet. Igény szerint a MessageEncoding beállítást Base64 értékre állíthatja a nem megfelelő üzenetek kezeléséhez.
Most már készen áll arra, hogy olyan kódot írjon, amely beolvassa az adatokat a Queue Storage-ba, és adatokat ír.
Üzenetsor létrehozása
Ez a példa bemutatja, hogyan hozhat létre üzenetsort:
//-------------------------------------------------
// Create a message queue
//-------------------------------------------------
public bool CreateQueue(string queueName)
{
try
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to create and manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
// Create the queue
queueClient.CreateIfNotExists();
if (queueClient.Exists())
{
Console.WriteLine($"Queue created: '{queueClient.Name}'");
return true;
}
else
{
Console.WriteLine($"Make sure the Azurite storage emulator running and try again.");
return false;
}
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}\n\n");
Console.WriteLine($"Make sure the Azurite storage emulator running and try again.");
return false;
}
}
Üzenet beszúrása egy üzenetsorba
Ha üzenetet szeretne beszúrni egy meglévő üzenetsorba, hívja meg a metódust SendMessage
. Az üzenetek lehetnek sztringek (UTF-8 formátumban) vagy bájttömbök. A következő kód létrehoz egy üzenetsort (ha nem létezik), és beszúr egy üzenetet:
//-------------------------------------------------
// Insert a message into a queue
//-------------------------------------------------
public void InsertMessage(string queueName, string message)
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to create and manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
// Create the queue if it doesn't already exist
queueClient.CreateIfNotExists();
if (queueClient.Exists())
{
// Send a message to the queue
queueClient.SendMessage(message);
}
Console.WriteLine($"Inserted: {message}");
}
Betekintés a következő üzenetbe
A metódus meghívásával betekinthet az üzenetsor üzeneteibe anélkül, hogy eltávolítaná őket az PeekMessages
üzenetsorból. Ha nem ad át értéket a maxMessages
paraméternek, az alapértelmezett érték az, hogy egy üzenetbe pillant.
//-------------------------------------------------
// Peek at a message in the queue
//-------------------------------------------------
public void PeekMessage(string queueName)
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
if (queueClient.Exists())
{
// Peek at the next message
PeekedMessage[] peekedMessage = queueClient.PeekMessages();
// Display the message
Console.WriteLine($"Peeked message: '{peekedMessage[0].Body}'");
}
}
Üzenetsorban található üzenet tartalmának módosítása
Egy üzenetet tartalmát helyben, az üzenetsorban módosíthatja. Ha az üzenet munkafeladatot jelöl, ezzel a funkcióval frissítheti a munkafeladat állapotát. Az alábbi kód frissíti az üzenetsorban található üzenetet az új tartalommal, és a láthatósági időkorlátot további 60 másodperccel bővíti. Elmenti az üzenethez társított feladat állapotát, és az ügyfél számára további egy percet biztosít az üzenet használatának folytatására. Ezzel a technikával nyomon követheti a többlépéses munkafolyamatokat az üzenetsor-üzeneteken anélkül, hogy elölről kellene kezdenie, ha egy feldolgozási lépés hardver- vagy szoftverhiba miatt meghiúsul. A rendszer általában nyilván tartja az újrapróbálkozások számát, és ha az üzenettel n alkalomnál többször próbálkoznak, akkor törlődik. Ez védelmet biztosít az ellen, hogy egy üzenetet minden feldolgozásakor kiváltson egy alkalmazáshibát.
//-------------------------------------------------
// Update an existing message in the queue
//-------------------------------------------------
public void UpdateMessage(string queueName)
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
if (queueClient.Exists())
{
// Get the message from the queue
QueueMessage[] message = queueClient.ReceiveMessages();
// Update the message contents
queueClient.UpdateMessage(message[0].MessageId,
message[0].PopReceipt,
"Updated contents",
TimeSpan.FromSeconds(60.0) // Make it invisible for another 60 seconds
);
}
}
A következő üzenet törlése
Üzenetsorból való lekérdezés két lépésben. A hívásakor ReceiveMessages
a következő üzenet egy üzenetsorba kerül. A visszaadott ReceiveMessages
üzenetek láthatatlanná válnak az üzenetsorból érkező üzeneteket olvasó többi kód számára. Alapértelmezés szerint az üzenet 30 másodpercig marad láthatatlan. Az üzenet üzenetsorból való eltávolításának befejezéséhez meg kell hívnia a következőt DeleteMessage
is: . Az üzenetek kétlépéses eltávolítása lehetővé teszi, hogy ha a kód hardver- vagy szoftverhiba miatt nem tud feldolgozni egy üzenetet, a kód egy másik példánya megkaphassa ugyanazt az üzenetet, és újra megpróbálkozhasson a feldolgozásával. A kód közvetlenül az üzenet feldolgozása után hív DeleteMessage
.
//-------------------------------------------------
// Process and remove a message from the queue
//-------------------------------------------------
public void DequeueMessage(string queueName)
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
if (queueClient.Exists())
{
// Get the next message
QueueMessage[] retrievedMessage = queueClient.ReceiveMessages();
// Process (i.e. print) the message in less than 30 seconds
Console.WriteLine($"Dequeued message: '{retrievedMessage[0].Body}'");
// Delete the message
queueClient.DeleteMessage(retrievedMessage[0].MessageId, retrievedMessage[0].PopReceipt);
}
}
A Async-Await minta használata gyakori Queue Storage API-kkal
Ez a példa bemutatja, hogyan használható a Async-Await minta a gyakori Queue Storage API-kkal. A minta meghívja az egyes metódusok aszinkron verzióját, ahogy azt az Async
egyes metódusok utótagja jelzi. Aszinkron metódus használata esetén a Async-Await minta felfüggeszti a helyi végrehajtást, amíg a hívás be nem fejeződik. Ez a viselkedés lehetővé teszi, hogy az aktuális szál más feladatokkal foglalkozzon. Ennek segítségével elkerülhetők a szűk keresztmetszetek a teljesítményben, és az alkalmazás általános válaszkészsége is javul. A Async-Await minta .NET-ben való használatával kapcsolatos további információkért lásd: Async and Await (C# és Visual Basic)
//-------------------------------------------------
// Perform queue operations asynchronously
//-------------------------------------------------
public async Task QueueAsync(string queueName)
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
// Create the queue if it doesn't already exist
await queueClient.CreateIfNotExistsAsync();
if (await queueClient.ExistsAsync())
{
Console.WriteLine($"Queue '{queueClient.Name}' created");
}
else
{
Console.WriteLine($"Queue '{queueClient.Name}' exists");
}
// Async enqueue the message
await queueClient.SendMessageAsync("Hello, World");
Console.WriteLine($"Message added");
// Async receive the message
QueueMessage[] retrievedMessage = await queueClient.ReceiveMessagesAsync();
Console.WriteLine($"Retrieved message with content '{retrievedMessage[0].Body}'");
// Async delete the message
await queueClient.DeleteMessageAsync(retrievedMessage[0].MessageId, retrievedMessage[0].PopReceipt);
Console.WriteLine($"Deleted message: '{retrievedMessage[0].Body}'");
// Async delete the queue
await queueClient.DeleteAsync();
Console.WriteLine($"Deleted queue: '{queueClient.Name}'");
}
További lehetőségek használata az üzenetek törléséhez
Két módon szabhatja testre az üzenetek lekérését egy üzenetsorból. Az első lehetőség az üzenetkötegek (legfeljebb 32) lekérése. A második lehetőség az, hogy beállít egy hosszabb vagy rövidebb láthatatlansági időkorlátot, így a kódnak lehetősége van hosszabb vagy rövidebb idő alatt teljesen feldolgozni az egyes üzeneteket.
Az alábbi példakód a ReceiveMessages
metódust használja 20 üzenet lekérésére egy hívásban. Ezután az egyes üzeneteket egy foreach
hurok használatával dolgozza fel. Mindemellett a láthatatlansági időkorlátot minden üzenethez öt percre állítja be. Vegye figyelembe, hogy az öt perc az összes üzenetnél egyszerre kezdődik, így a hívás ReceiveMessages
óta eltelt öt perc után a nem törölt üzenetek ismét láthatók lesznek.
//-----------------------------------------------------
// Process and remove multiple messages from the queue
//-----------------------------------------------------
public void DequeueMessages(string queueName)
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
if (queueClient.Exists())
{
// Receive and process 20 messages
QueueMessage[] receivedMessages = queueClient.ReceiveMessages(20, TimeSpan.FromMinutes(5));
foreach (QueueMessage message in receivedMessages)
{
// Process (i.e. print) the messages in less than 5 minutes
Console.WriteLine($"De-queued message: '{message.Body}'");
// Delete the message
queueClient.DeleteMessage(message.MessageId, message.PopReceipt);
}
}
}
Az üzenetsor hosszának lekérése
Megbecsülheti egy üzenetsorban található üzenetek számát. A GetProperties
metódus üzenetsor-tulajdonságokat ad vissza, beleértve az üzenetszámot is. A ApproximateMessagesCount
tulajdonság az üzenetsorban lévő üzenetek hozzávetőleges számát tartalmazza. Ez a szám nem alacsonyabb, mint az üzenetsorban lévő üzenetek tényleges száma, de magasabb is lehet.
//-----------------------------------------------------
// Get the approximate number of messages in the queue
//-----------------------------------------------------
public void GetQueueLength(string queueName)
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
if (queueClient.Exists())
{
QueueProperties properties = queueClient.GetProperties();
// Retrieve the cached approximate message count.
int cachedMessagesCount = properties.ApproximateMessagesCount;
// Display number of messages.
Console.WriteLine($"Number of messages in queue: {cachedMessagesCount}");
}
}
Üzenetsor törlése
Ha törölni szeretne egy üzenetsort és az abban található összes üzenetet, hívja meg a metódust Delete
a queue objektumon.
//-------------------------------------------------
// Delete the queue
//-------------------------------------------------
public void DeleteQueue(string queueName)
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
if (queueClient.Exists())
{
// Delete the queue
queueClient.Delete();
}
Console.WriteLine($"Queue deleted: '{queueClient.Name}'");
}
Következő lépések
Most, hogy megismerte a Queue Storage alapjait, kövesse ezeket a hivatkozásokat az összetettebb tárolási feladatok megismeréséhez.
- Az elérhető API-kkal kapcsolatos részletes információkért tekintse meg a Queue Storage referenciadokumentációját:
- Az Azure-ban való adattárolás további lehetőségeiről tekintse meg a többi szolgáltatás-útmutatót.
- Ismerkedés az Azure Table Storage szolgáltatással a .NET használatával strukturált adatok tárolásához.
- Első lépések Azure Blob Storage a .NET használatával strukturálatlan adatok tárolására.
- Csatlakozzon az SQL Database adatbázishoz .NET (C#) használatával a relációs adatok tárolásához.
- Megtudhatja, hogyan egyszerűsítheti le az Azure Storage-hoz írt kódot az Azure WebJobs SDK használatával.
Az elavult .NET-verziójú 11.x SDK-kkal kapcsolatos kódmintákért lásd: Kódminták a .NET 11.x verziójával.