البرنامج التعليمي: العمل باستخدام قوائم انتظار Azure Queue Storage في .NET

يبادر Azure Queue Storage بتنفيذ قوائم الانتظار المستندة إلى السحابة لتمكين الاتصال بين مكونات تطبيق موزع. تحتفظ كل قائمة انتظار بقائمة رسائل يمكن إضافتها بواسطة مكون مرسل ومعالجتها بواسطة مكون مستقبل. باستخدام قائمة انتظار، يمكن توسيع تطبيقك على الفور ليفي بالمتطلبات. تعرض هذه المقالة الخطوات الأساسية للعمل باستخدام قائمة انتظار Azure Queue Storage.

في هذا البرنامج التعليمي، تتعلم كيفية:

  • أنشئ حساب Azure Storage
  • إنشاء التطبيق
  • إضافة مكتبات عميل Azure
  • إضافة دعم للتعليمات البرمجية غير المتزامنة
  • إنشاء قائمة انتظار
  • إدراج رسائل في قائمة انتظار
  • إلغاء ترتيب الرسائل
  • حذف قائمة انتظار فارغة
  • التحقق من وجود وسيطات سطر الأوامر
  • إنشاء وتشغيل التطبيق

المتطلبات الأساسية

  • احصل على نسختك المجانية من محرر Visual Studio Code عبر النظام الأساسي.
  • بادر بتنزيل وتثبيت .NET Core SDK الإصدار 3.1 أو أحدث.
  • في حال لم يكن لديك اشتراك Azure حالي، يُمكنك إنشاء حساب مجاني قبل البدء.

أنشئ حساب Azure Storage

أولاً، قم بإنشاء حساب تخزين Azure. للحصول على دليل خطوة بخطوة لإنشاء حساب تخزين، راجع إنشاء حساب تخزين. هذه خطوة منفصلة تقوم بتنفيذها بعد إنشاء حساب Azure مجاني في المتطلبات الأساسية.

إنشاء التطبيق

أنشئ تطبيق .NET Core يسمى QueueApp. للتبسيط، سيرسل هذا التطبيق الرسائل ويستقبلها عبر قائمة الانتظار.

  1. في نافذة وحدة تحكم (مثل cmd أو PowerShell أو Azure CLI) استخدم الأمر dotnet new⁩ لإنشاء تطبيق وحدة تحكم جديد يحمل الاسم ⁧QueueApp⁩. يُنشئ هذا الأمر مشروع "hello world" C# بسيط مع ملف مصدر واحد يسمى Program.cs.

    dotnet new console -n QueueApp
    
  2. التبديل إلى المجلد الذي تم إنشاؤه حديثًا ⁧QueueApp⁩ وبناء التطبيق للتحقق من أن كل شيء على ما يرام.

    cd QueueApp
    
    dotnet build
    

    ينبغي أن ترى نتائج مشابهة للإخراج التالي:

    C:\Tutorials>dotnet new console -n QueueApp
    The template "Console Application" was created successfully.
    
    Processing post-creation actions...
    Running 'dotnet restore' on QueueApp\QueueApp.csproj...
      Restore completed in 155.63 ms for C:\Tutorials\QueueApp\QueueApp.csproj.
    
    Restore succeeded.
    
    C:\Tutorials>cd QueueApp
    
    C:\Tutorials\QueueApp>dotnet build
    Microsoft (R) Build Engine version 16.0.450+ga8dc7f1d34 for .NET Core
    Copyright (C) Microsoft Corporation. All rights reserved.
    
      Restore completed in 40.87 ms for C:\Tutorials\QueueApp\QueueApp.csproj.
      QueueApp -> C:\Tutorials\QueueApp\bin\Debug\netcoreapp3.1\QueueApp.dll
    
    Build succeeded.
        0 Warning(s)
        0 Error(s)
    
    Time Elapsed 00:00:02.40
    
    C:\Tutorials\QueueApp>_
    

إضافة مكتبات عميل Azure

  1. أضف مكتبات عميل Azure Storage إلى المشروع باستخدام الأمر dotnet add package.

    يمكنك تشغيل الأمر التالي من مجلد المشروع في نافذة وحدة التحكم.

    dotnet add package Azure.Storage.Queues
    

الإضافة عبارات الاستخدام

  1. من سطر الأوامر في دليل المشروع، اكتب code . لفتح Visual Studio Code في الدليل الحالي. اترك نافذة سطر الأوامر مفتوحة. سيكون هناك المزيد من الأوامر لتشغيلها لاحقًا. إذا تمت مطالبتك بإضافة أصول C# المطلوبة للبناء وتصحيح الأخطاء، فانقر فوق الزر نعم.

  2. افتح الملف المصدر Program.cs وأضف مساحات الأسماء التالية مباشرة بعد العبارة using System;. يستخدم هذا التطبيق أنواعًا من مساحات الأسماء هذه للاتصال بـ Azure Storage والعمل باستخدام قوائم الانتظار.

    using System.Threading.Tasks;
    using Azure.Storage.Queues;
    using Azure.Storage.Queues.Models;
    
  3. احفظ ⁧الملف Program.cs⁩.

إضافة دعم للتعليمات البرمجية غير المتزامنة

نظرًا لأن التطبيق يستخدم موارد السحابة، يتم تشغيل التعليمات البرمجية بشكل غير متزامن.

  1. حدّث أسلوب Main للتشغيل بشكل غير متزامن. استبدل void بالقيمة المرتجعة async Task.

    static async Task Main(string[] args)
    
  2. احفظ ⁧الملف Program.cs⁩.

إنشاء قائمة انتظار

قبل إجراء أي مكالمات في واجهات برمجة تطبيقات Azure، يجب أن تحصل على بيانات اعتمادك من مدخل Azure.

نسخ بيانات الاعتماد الخاصة بك من مدخل Azure.

عندما يقوم نموذج التطبيق بإجراء طلب إلىAzure Storage، يجب أن يكون معتمدًا. لاعتماد طلب محدد، أضف بيانات اعتماد حساب التخزين إلى التطبيق كسلسلة اتصال. لعرض بيانات اعتماد حساب التخزين الخاص بك، اتبع الخطوات التالية:

  1. تسجيل الدخول إلى ⁧⁩مدخل Azure⁧⁩.

  2. حدد موقع حساب التخزين الخاص بك.

  3. في جزء قائمة حساب التخزين، ضمن ⁧⁩"Security + networking"⁧⁩، حدد ⁧⁩"Access keys"⁧⁩. هنا، يمكنك عرض مفاتيح الوصول إلى الحساب، وسلسلة الاتصال الكامل لكل مفتاح.

    لقطة شاشة توضح مكان إعدادات مفتاح الوصول في مدخل Azure.

  4. في جزء ⁧⁩"Access keys"⁧⁩ حدد ⁧⁩"Show keys"⁧⁩.

  5. في المقطع ⁧⁩key1⁧⁩ حدد قيمة ⁧⁩⁩Connection string⁦⁩. حدد أيقونة ⁧⁩Copy to clipboard⁧⁩، لنسخ سلسلة الاتصال. ستضيف قيمة سلسلة الاتصال إلى متغير البيئة في القسم التالي.

    توضح Screenshot كيفية نسخ سلسلة اتصال من مدخل Microsoft Azure

قم بتهيئة سلسلة اتصال التخزين الخاصة بك

بعد نسخ سلسلة الاتصال، سجله في متغير البيئة الجديد على الجهاز المحلي الذي يقوم بتشغيل التطبيق. لتعيين متغير البيئة، افتح نافذة منصة التحكم، واتبع الإرشادات الخاصة بنظام التشغيل. استبدل ⁧<yourconnectionstring>⁩ بسلسلة الاتصال الفعلية الخاصة بك.

setx AZURE_STORAGE_CONNECTION_STRING "<yourconnectionstring>"

بعد إضافة متغير البيئة في Windows، يجب بدء تشغيل مثيل جديد من نافذة الأمر.

إعادة تشغيل البرامج

بعد إضافة متغير البيئة، أعد تشغيل أية برامج قيد التشغيل، والتي ستحتاج إلى قراءة متغير البيئة. على سبيل المثال، أعد تشغيل بيئة التطوير أو المحرر الخاص بك قبل المتابعة.

إضافة سلسلة الاتصال إلى التطبيق.

أضف سلسلة الاتصال في التطبيق بحيث يمكنه الوصول إلى حساب التخزين.

  1. ارجع إلى Visual Studio Code.

  2. في أسلوب Main، استبدل التعليمات البرمجية Console.WriteLine("Hello, World"); بالسطر التالي الذي يحصل على سلسلة الاتصال من متغير البيئة.

    string connectionString = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING");
    
  3. أضف التعليمات البرمجية التالية إلى Main لإنشاء كائن قائمة انتظار، الذي يتم تمريره بعد ذلك إلى أسلوبي الإرسال والاستقبال.

    QueueClient queue = new QueueClient(connectionString, "mystoragequeue");
    
  4. احفظ الملف.

إدراج رسائل في قائمة الانتظار

أنشئ أسلوب جديد لإرسال رسالة إلى قائمة الانتظار.

  1. أضف أسلوب InsertMessageAsync التالي إلى فئة Program.

    يتم تمرير هذا الأسلوب إلى مرجع قائمة انتظار. يتم إنشاء قائمة انتظار جديدة، إذا لم تكن موجودة بالفعل، عن طريق استدعاء CreateIfNotExistsAsync. ثم، يضيف newMessage إلى قائمة الانتظار عن طريق استدعاء SendMessageAsync.

    static async Task InsertMessageAsync(QueueClient theQueue, string newMessage)
    {
        if (null != await theQueue.CreateIfNotExistsAsync())
        {
            Console.WriteLine("The queue was created.");
        }
    
        await theQueue.SendMessageAsync(newMessage);
    }
    
  2. اختياري: يبلغ الحد الأقصى لمدة حياة الرسالة سبعة أيام بشكل افتراضي. يمكن تحديد أي رقم موجب لوقت بقاء الرسالة. تضيف قصاصة التعليمات البرمجية التالية رسالة لا تنتهي صلاحيتها أبدًا.

    لإضافة رسالة لا تنتهي صلاحيتها، استخدم Timespan.FromSeconds(-1) في مكالمتك لـ SendMessageAsync.

    await theQueue.SendMessageAsync(newMessage, default, TimeSpan.FromSeconds(-1), default);
    
  3. احفظ الملف.

يجب أن تكون رسالة قائمة الانتظار بتنسيق متوافق مع طلب XML باستخدام ترميز UTF-8. يمكن أن يصل حجم الرسالة إلى 64 كيلوبايت. إذا كانت الرسالة تحتوي على بيانات ثنائية، فبادر بترميز الرسالة باستخدام Base64.

إلغاء ترتيب الرسائل

أنشئ أسلوب جديد لاسترداد رسالة من قائمة الانتظار. بمجرد تلقي الرسالة بنجاح، من المهم حذفها من قائمة الانتظار حتى لا تتم معالجتها أكثر من مرة.

  1. أضف أسلوب جديد يسمى RetrieveNextMessageAsync إلى فئة Program.

    يتلقى هذا الأسلوب رسالة من قائمة الانتظار عن طريق استدعاء ReceiveMessagesAsync، وتمرير 1 في المعلمة الأولى لاسترداد الرسالة التالية فقط في قائمة الانتظار. بعد تلقي الرسالة، احذفها من قائمة الانتظار عن طريق استدعاء DeleteMessageAsync .

    عندما يتم إرسال رسالة إلى قائمة الانتظار بإصدار من SDK قبل v12، يتم تلقائيا ترميزها باستخدام Base64. تمت إزالة هذه الوظيفة بدءًا من v12. عند استرداد رسالة باستخدام SDK v12، فإنه لا يتم فك ترميزها تلقائيًا باستخدام Base64. يجب أن تبادر بفك ترميز المحتويات باستخدام Base64 بنفسك.

    static async Task<string> RetrieveNextMessageAsync(QueueClient theQueue)
    {
        if (await theQueue.ExistsAsync())
        {
            QueueProperties properties = await theQueue.GetPropertiesAsync();
    
            if (properties.ApproximateMessagesCount > 0)
            {
                QueueMessage[] retrievedMessage = await theQueue.ReceiveMessagesAsync(1);
                string theMessage = retrievedMessage[0].Body.ToString();
                await theQueue.DeleteMessageAsync(retrievedMessage[0].MessageId, retrievedMessage[0].PopReceipt);
                return theMessage;
            }
    
            return null;
        }
    
        return null;
    }
    
  2. احفظ الملف.

حذف قائمة انتظار فارغة

إنها أفضل ممارسة في نهاية المشروع أن تحدد ما إذا كنت لا تزال تحتاج الموارد التي أنشأتها. الموارد المتروكة قيد التشغيل يمكن أن تكلفك المال. إذا كانت قائمة الانتظار موجودة ولكنها فارغة، فاسأل المستخدم ما إذا كان يرغب في حذفها.

  1. بادر بتوسيع أسلوب RetrieveNextMessageAsync لتضمين مطالبة لحذف قائمة الانتظار الفارغة.

    static async Task<string> RetrieveNextMessageAsync(QueueClient theQueue)
    {
        if (await theQueue.ExistsAsync())
        {
            QueueProperties properties = await theQueue.GetPropertiesAsync();
    
            if (properties.ApproximateMessagesCount > 0)
            {
                QueueMessage[] retrievedMessage = await theQueue.ReceiveMessagesAsync(1);
                string theMessage = retrievedMessage[0].Body.ToString();
                await theQueue.DeleteMessageAsync(retrievedMessage[0].MessageId, retrievedMessage[0].PopReceipt);
                return theMessage;
            }
            else
            {
                Console.Write("The queue is empty. Attempt to delete it? (Y/N) ");
                string response = Console.ReadLine();
    
                if (response.ToUpper() == "Y")
                {
                    await theQueue.DeleteIfExistsAsync();
                    return "The queue was deleted.";
                }
                else
                {
                    return "The queue was not deleted.";
                }
            }
        }
        else
        {
            return "The queue does not exist. Add a message to the command line to create the queue and store the message.";
        }
    }
    
  2. احفظ الملف.

التحقق من وجود وسيطات سطر الأوامر

إذا كانت هناك أي وسيطات سطر أوامر تم تمريرها إلى التطبيق، افترض أنها رسالة يمكن إضافتها إلى قائمة الانتظار. بادر بضم الوسيطات معًا لإنشاء سلسلة. أضف هذه السلسلة إلى قائمة انتظار الرسائل عن طريق استدعاء أسلوب InsertMessageAsync الذي أضفناه سابقًا.

إذا لم تكن هناك وسيطات سطر أوامر، حاول استرداد العملية. بادر باستدعاء أسلوب RetrieveNextMessageAsync لاسترداد الرسالة التالية في قائمة الانتظار.

وأخيرًا، انتظر إدخال المستخدم قبل الخروج عن طريق استدعاء Console.ReadLine.

  1. بادر بتوسيع أسلوب Main للتحقق من وجود وسيطات سطر الأوامر وانتظر إدخال المستخدم.

    static async Task Main(string[] args)
    {
        string connectionString = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING");
    
        QueueClient queue = new QueueClient(connectionString, "mystoragequeue");
    
        if (args.Length > 0)
        {
            string value = String.Join(" ", args);
            await InsertMessageAsync(queue, value);
            Console.WriteLine($"Sent: {value}");
        }
        else
        {
            string value = await RetrieveNextMessageAsync(queue);
            Console.WriteLine($"Received: {value}");
        }
    
        Console.Write("Press Enter...");
        Console.ReadLine();
    }
    
  2. احفظ الملف.

تعليمة برمجية كاملة

إليك قائمة التعليمات البرمجية الكاملة لهذا المشروع.

using System;
using System.Threading.Tasks;
using Azure.Storage.Queues;
using Azure.Storage.Queues.Models;

namespace QueueApp
{
    class Program
    {
        static async Task Main(string[] args)
        {
            string connectionString = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING");

            QueueClient queue = new QueueClient(connectionString, "mystoragequeue");

            if (args.Length > 0)
            {
                string value = String.Join(" ", args);
                await InsertMessageAsync(queue, value);
                Console.WriteLine($"Sent: {value}");
            }
            else
            {
                string value = await RetrieveNextMessageAsync(queue);
                Console.WriteLine($"Received: {value}");
            }

            Console.Write("Press Enter...");
            Console.ReadLine();
        }

        static async Task InsertMessageAsync(QueueClient theQueue, string newMessage)
        {
            if (null != await theQueue.CreateIfNotExistsAsync())
            {
                Console.WriteLine("The queue was created.");
            }

            await theQueue.SendMessageAsync(newMessage);
        }

        static async Task<string> RetrieveNextMessageAsync(QueueClient theQueue)
        {
            if (await theQueue.ExistsAsync())
            {
                QueueProperties properties = await theQueue.GetPropertiesAsync();

                if (properties.ApproximateMessagesCount > 0)
                {
                    QueueMessage[] retrievedMessage = await theQueue.ReceiveMessagesAsync(1);
                    string theMessage = retrievedMessage[0].Body.ToString();
                    await theQueue.DeleteMessageAsync(retrievedMessage[0].MessageId, retrievedMessage[0].PopReceipt);
                    return theMessage;
                }
                else
                {
                    Console.Write("The queue is empty. Attempt to delete it? (Y/N) ");
                    string response = Console.ReadLine();

                    if (response.ToUpper() == "Y")
                    {
                        await theQueue.DeleteIfExistsAsync();
                        return "The queue was deleted.";
                    }
                    else
                    {
                        return "The queue was not deleted.";
                    }
                }
            }
            else
            {
                return "The queue does not exist. Add a message to the command line to create the queue and store the message.";
            }
        }
    }
}

إنشاء وتشغيل التطبيق

  1. من سطر الأوامر في دليل المشروع، بادر بتشغيل أمر dotnet التالي لبناء المشروع.

    dotnet build
    
  2. بعد بناء المشروع بنجاح، بادر بتشغيل الأمر التالي لإضافة الرسالة الأولى إلى قائمة الانتظار.

    dotnet run First queue message
    

    ينبغي لك أن تشاهد هذا الإخراج:

    C:\Tutorials\QueueApp>dotnet run First queue message
    The queue was created.
    Sent: First queue message
    Press Enter..._
    
  3. يمكنك تشغيل التطبيق بدون وسيطات سطر الأوامر لتلقي وإزالة الرسالة الأولى في قائمة الانتظار.

    dotnet run
    
  4. تابع تشغيل التطبيق حتى تتم إزالة جميع الرسائل. إذا قمت بتشغيله مرة أخرى، فستحصل على رسالة مفادها أن قائمة الانتظار فارغة ومطالبة بحذف قائمة الانتظار.

    C:\Tutorials\QueueApp>dotnet run First queue message
    The queue was created.
    Sent: First queue message
    Press Enter...
    
    C:\Tutorials\QueueApp>dotnet run Second queue message
    Sent: Second queue message
    Press Enter...
    
    C:\Tutorials\QueueApp>dotnet run Third queue message
    Sent: Third queue message
    Press Enter...
    
    C:\Tutorials\QueueApp>dotnet run
    Received: First queue message
    Press Enter...
    
    C:\Tutorials\QueueApp>dotnet run
    Received: Second queue message
    Press Enter...
    
    C:\Tutorials\QueueApp>dotnet run
    Received: Third queue message
    Press Enter...
    
    C:\Tutorials\QueueApp>dotnet run
    The queue is empty. Attempt to delete it? (Y/N) Y
    Received: The queue was deleted.
    Press Enter...
    
    C:\Tutorials\QueueApp>_
    

الخطوات التالية

في هذا البرنامج التعليمي، نتعلم طريقة القيام بما يأتي:

  1. إنشاء قائمة انتظار
  2. إضافة الرسائل وإزالتها من قائمة انتظار
  3. حذف قائمة انتظار Azure Queue Storage

تحقق من قوالب التشغيل السريع لـ Azure Queue Storage للحصول على مزيد من المعلومات.

للحصول على نماذج التعليمات البرمجية ذات الصلة باستخدام حزم SDK للإصدار 11.x من .NET المهملة، راجع نماذج التعليمات البرمجية باستخدام .NET الإصدار 11.x.