قم بتطوير وظائف مكتبة فئة C # باستخدام Azure Functions

هام

سينتهي الدعم للنموذج قيد التنفيذ في 10 نوفمبر 2026. نوصي بشدة بترحيل تطبيقاتك إلى نموذج العامل المعزول للحصول على الدعم الكامل.

هذه المقالة مقدمة لتطوير Azure Functions باستخدام C# في مكتبات فئة .NET. تستخدم مكتبات الفئات هذه للتشغيل قيد المعالجة مع وقت تشغيل الوظائف. يمكن تشغيل وظائف .NET بدلا من ذلك _isolated من وقت تشغيل الوظائف، والذي يوفر العديد من المزايا. لمعرفة المزيد، راجع نموذج العامل المعزول. للمقارنة الشاملة بين هذين النموذجين، راجع الاختلافات بين النموذج قيد المعالجة ونموذج العامل المعزول.

هام

تدعم هذه المقالة وظائف مكتبة فئة .NET التي تعمل في العملية مع وقت التشغيل. يمكن أيضًا أن تعمل وظائف C # الخاصة بك خارج العملية ومعزولة عن وقت تشغيل الوظائف. نموذج عملية العامل المعزول هو الطريقة الوحيدة لتشغيل إصدارات غير LTS من تطبيقات .NET و.NET Framework في الإصدارات الحالية من وقت تشغيل الوظائف. لمعرفة المزيد، راجع وظائف معالجة العامل المعزولة .NET. للمقارنة الشاملة بين عملية العامل المعزولة ووظائف .NET قيد المعالجة، راجع الاختلافات بين العملية قيد المعالجة وعزل دالات .NET Azure.

كمطور C # ، قد تكون مهتما أيضا بأحد المقالات التالية:

الشروع في العمل المفاهيم التعلم الموجه /العينات

يدعم Azure Functions لغات البرمجة النصية C# وC#. إذا كنت تبحث عن إرشادات حول استخدام C# في مدخل Azure، راجع مرجع مطور البرنامج النصي C# (.csx).

الإصدارات المدعومة

تدعم إصدارات وقت تشغيل الوظائف إصدارات معينة من .NET. لمعرفة المزيد عن إصدارات الوظائف، راجع نظرة عامة على إصدارات وقت تشغيل وظائف Azure. يعتمد دعم الإصدار أيضا على ما إذا كانت وظائفك تعمل في العملية أو عملية عامل معزولة.

إشعار

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

يعرض الجدول التالي أعلى مستوى من .NET أو .NET Framework الذي يمكن استخدامه مع إصدار معين من Functions.

إصدار وقت تشغيل الوظائف نموذج عامل معزول النموذجقيد المعالجة 5
الوظائف 4.x .NET 8.0
.NET 7.01
.NET 6.02
.NET Framework 4.83
.NET 6.02
الدالات 1.x4 غير متوفر .NET Framework 4.8

1.NET 7 يصل إلى نهاية الدعم الرسمي في 14 مايو 2024.
2.NET 6 يصل إلى نهاية الدعم الرسمي في 12 نوفمبر 2024.
3 تتطلب عملية الإنشاء أيضا .NET SDK. 4 ينتهي الدعم للإصدار 1.x من وقت تشغيل Azure Functions في 14 سبتمبر 2026. لمزيد من المعلومات، راجع إعلان الدعم هذا. للحصول على الدعم الكامل المستمر، يجب ترحيل تطبيقاتك إلى الإصدار 4.x.
5 ينتهي الدعم للنموذج قيد المعالجة في 10 نوفمبر 2026. لمزيد من المعلومات، راجع إعلان الدعم هذا. للحصول على الدعم الكامل المستمر، يجب ترحيل تطبيقاتك إلى نموذج العامل المعزول.

للحصول على أحدث الأخبار حول إصدارات Azure Functions، بما في ذلك إزالة إصدارات ثانوية قديمة معينة، راقب إعلانات Azure App Service.

مشروع مكتبة فئة الوظائف

في Visual Studio، يقوم قالب مشروع Azure Functions بإنشاء مشروع مكتبة فئة C# يحتوي على الملفات التالية:

  • host.json - يخزن إعدادات التكوين التي تؤثر على كافة الوظائف في المشروع عند التشغيل محليا أو في Azure.
  • local.settings.json: يستخدم لتخزين إعدادات التطبيق وسلاسل الاتصال عند التشغيل محليا. يحتوي هذا الملف على أسرار ولا يتم نشره على تطبيق الوظائف في Azure. بدلا من ذلك، أضف إعدادات التطبيق إلى تطبيق الوظائف.

عند إنشاء المشروع، يتم إنشاء بنية مجلد الذي يبدو مثل المثال التالي في دليل الإخراج البنية:

<framework.version>
 | - bin
 | - MyFirstFunction
 | | - function.json
 | - MySecondFunction
 | | - function.json
 | - host.json

هذا الدليل هو ما يحصل نشرها على التطبيق وظيفة الخاص بك في Azure. ملحقات الربط المطلوبة في الإصدار 2.x من وقت تشغيل الوظائف تضاف إلى المشروع كحزم NuGet.

هام

إنشاء عملية إنشاء function.json في الملف لكل وظيفة. لا يقصد بهذه function.jsonفي الملف أن يتم تحريرها مباشرة. لا يمكنك تغيير تكوين الربط أو تعطيل الوظيفة عن طريق تحرير هذا الملف. لمعرفة كيفية تعطيل وظيفة، راجع كيفية تعطيل الوظائف.

الأساليب المعترف بها كوظائف

في مكتبة الفئات، الدالة هي أسلوب مع سمة FunctionName مشغل و، كما هو موضح في المثال التالي:

public static class SimpleExample
{
    [FunctionName("QueueTrigger")]
    public static void Run(
        [QueueTrigger("myqueue-items")] string myQueueItem, 
        ILogger log)
    {
        log.LogInformation($"C# function processed: {myQueueItem}");
    }
} 

تحدد السمة FunctionName الطريقة كنقطة إدخال وظيفة. يجب أن يكون الاسم فريدًا داخل المشروع، وأن يبدأ بحرف ولا يحتوي إلا على أحرف وأرقام و_ و- بحد أقصى 127 حرف. غالبًا ما تنشئ قوالب المشروع أسلوبًا يُسمى Run، ولكن يمكن أن يكون اسم الطريقة أي اسم صالح لأسلوب C#. يوضح المثال أعلاه أسلوبا ثابتا يتم استخدامه، ولكن لا يلزم أن تكون الوظائف ثابتة.

تحدد سمة المشغل نوع المشغل وتربط بيانات الإدخال بمعلمة الأسلوب. يتم تشغيل وظيفة المثال السابق من خلال رسالة قائمة انتظار، ويتم تمرير رسالة قائمة الانتظار إلى الأسلوب في myQueueItemالمعلمة.

معلمات توقيع الأسلوب

قد يحتوي توقيع الأسلوب على معلمات أخرى غير تلك المستخدمة مع سمة المشغل. فيما يلي بعض المعلمات الأخرى التي يمكنك تضمينها:

ترتيب المعلمات في توقيع الوظيفة لا يهم. على سبيل المثال، يمكنك وضع معلمات المشغل قبل أو بعد الارتباطات الأخرى، ويمكنك وضع معلمة المسجل قبل أو بعد مشغل أو معلمات الربط.

روابط الإخراج

يمكن أن تحتوي الدالة على صفر أو روابط إخراج متعددة معرفة باستخدام معلمات الإخراج.

المثال التالي يعدل السابق بإضافة ربط قائمة انتظار إخراج مسمى myQueueItemCopy. تكتب الوظيفة محتويات الرسالة التي تقوم بتشغيل الوظيفة إلى رسالة جديدة في قائمة انتظار مختلفة.

public static class SimpleExampleWithOutput
{
    [FunctionName("CopyQueueMessage")]
    public static void Run(
        [QueueTrigger("myqueue-items-source")] string myQueueItem, 
        [Queue("myqueue-items-destination")] out string myQueueItemCopy,
        ILogger log)
    {
        log.LogInformation($"CopyQueueMessage function processed: {myQueueItem}");
        myQueueItemCopy = myQueueItem;
    }
}

تتم كتابة القيم المعينة لربطات الإخراج عند إنهاء الوظيفة. يمكنك استخدام أكثر من ربط إخراج واحد في دالة ببساطة عن طريق تعيين قيم لمعلمات إخراج متعددة.

تشرح المقالات المرجعية الملزمة (قوائم انتظار التخزين،على سبيل المثال) شرح أنواع المعلمات التي يمكنك استخدامها مع سمات ربط المشغل أو الإدخال أو الإخراج.

مثال تعبيرات الربط

التعليمات البرمجية التالية تحصل على اسم قائمة الانتظار للمراقبة من إعداد التطبيق، وتحصل على وقت إنشاء رسالة قائمة الانتظار في insertionTime المعلمة.

public static class BindingExpressionsExample
{
    [FunctionName("LogQueueMessage")]
    public static void Run(
        [QueueTrigger("%queueappsetting%")] string myQueueItem,
        DateTimeOffset insertionTime,
        ILogger log)
    {
        log.LogInformation($"Message content: {myQueueItem}");
        log.LogInformation($"Created at: {insertionTime}");
    }
}

function.json تم تجديدها تلقائيا

تنشئ عملية البنية function.json ملف في مجلد الوظيفة في مجلد البنية. كما ذكرنا سابقا، لا يقصد بتحرير هذا الملف مباشرة. لا يمكنك تغيير تكوين الربط أو تعطيل الوظيفة عن طريق تحرير هذا الملف.

الغرض من هذا الملف هو توفير معلومات لوحدة تحكم المقياس لاستخدامها في تغيير حجم القرارات المتعلقة بخطة الاستهلاك. لهذا السبب، يحتوي الملف فقط على معلومات المشغل، وليس روابط الإدخال/الإخراج.

يتضمن function.json التي تم إنشاؤها في الملف configurationSource خاصية تخبر وقت التشغيل لاستخدام سمات .NET للروابط، بدلًا من تكوين function.json. إليك مثال:

{
  "generatedBy": "Microsoft.NET.Sdk.Functions-1.0.0.0",
  "configurationSource": "attributes",
  "bindings": [
    {
      "type": "queueTrigger",
      "queueName": "%input-queue-name%",
      "name": "myQueueItem"
    }
  ],
  "disabled": false,
  "scriptFile": "..\\bin\\FunctionApp1.dll",
  "entryPoint": "FunctionApp1.QueueTrigger.Run"
}

Microsoft.NET.Sdk.Functions

يتم تنفيذ إنشاء ملف function.json بواسطة حزمة Microsoft.NET.Sdk.Functions.

يوضح المثال التالي الأجزاء ذات الصلة من الملفات .csproj التي لها أطر عمل هدف مختلفة لنفس الحزمة Sdk :

<PropertyGroup>
  <TargetFramework>net6.0</TargetFramework>
  <AzureFunctionsVersion>v4</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
  <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.1.1" />
</ItemGroup>

بين Sdk تبعيات الحزمة مشغلات وروابط. يشير مشروع 1.x إلى مشغلات وروابط 1.x لأن هذه المشغلات والروابط تستهدف .NET Framework، بينما تستهدف مشغلات وروابط 4.x .NET Core.

Sdkتعتمد الحزمة أيضا على Newtonsoft.Json، وبشكل غير مباشر على WindowsAzure.Storage. تأكد من أن المشروع الخاص بك يستخدم إصدارات تلك الحزم التي تعمل مع إصدار وقت تشغيل Functions الذي يستهدفه هذا المشروع. على سبيل المثال، Newtonsoft.Json يحتوي على الإصدار 11 .NET Framework 4.6.1 ولكن وقت تشغيل Functions التي تستهدف .NET Framework 4.6.1 متوافق فقط مع Newtonsoft.Json 9.0.1. لذا فإن رمز الدالة في هذا المشروع يجب أن يستخدم Newtonsoft.Json 9.0.1.

التعليمات البرمجية لـ Microsoft.NET.Sdk.Functions متاحة في GitHub repo azure-functions-vs-build-sdk

إصدار وقت التشغيل المحلي

يستخدم Visual Studio أدوات Azure الأساسية دالات لتشغيل مشاريع Functions على الكمبيوتر المحلي. الأدوات الأساسية هي واجهة سطر الأوامر لوقت تشغيل الوظائف.

إذا قمت بتثبيت Core Tools باستخدام حزمة مثبت Windows (MSI) أو باستخدام npm، فلن يؤثر ذلك على إصدار Core Tools المستخدم من قبل Visual Studio. بالنسبة إلى إصدار وقت التشغيل الدالات 1.x، Visual Studio يخزن إصدارات الأدوات الأساسية في ٪USERPROFILE٪\AppData\Local\Azure.Functions.Cli ويستخدم أحدث إصدار مخزن هناك. بالنسبة إلى Functions 4.x، يتم تضمين Core Tools في ملحق Azure Functions وWeb Jobs Tools . بالنسبة إلى Functions 1.x، يمكنك معرفة الإصدار المستخدم في إخراج وحدة التحكم عند تشغيل مشروع Functions:

[3/1/2018 9:59:53 AM] Starting Host (HostId=contoso2-1518597420, Version=2.0.11353.0, ProcessId=22020, Debug=False, Attempt=0, FunctionsExtensionVersion=)

ReadyToRun

يمكنك ترجمة تطبيق الوظائف الخاص بك مثل ثنائيات ReadyToRun . ReadyToRun هو شكل من أشكال التحويل البرمجي قبل الموعد الذي يمكن أن يحسن أداء بدء التشغيل للمساعدة في تقليل تأثير التشغيل البارد عند التشغيل في خطة الاستهلاك.

ReadyToRun متوفر في .NET 6 والإصدارات الأحدث ويتطلب الإصدار 4.0 من وقت تشغيل Azure Functions.

لتحويل مشروعك إلى ReadyToRun، قم بتحديث ملف المشروع الخاص بك عن طريق إضافة <PublishReadyToRun><RuntimeIdentifier> العناصر. فيما يلي تكوين النشر إلى تطبيق وظائف Windows 32 بت.

<PropertyGroup>
  <TargetFramework>net6.0</TargetFramework>
  <AzureFunctionsVersion>v4</AzureFunctionsVersion>
  <PublishReadyToRun>true</PublishReadyToRun>
  <RuntimeIdentifier>win-x86</RuntimeIdentifier>
</PropertyGroup>

هام

بدءا من .NET 6، تمت إضافة دعم تجميع ReadyToRun المركب. تحقق من قيود النظام الأساسي والهندسة المعمارية ReadyToRun Cross.

يمكنك أيضا إنشاء التطبيق الخاص بك مع ReadyToRun من سطر الأوامر. لمزيد من المعلومات، راجع -p:PublishReadyToRun=true الخيار في dotnet publish.

الأنواع المعتمدة للروابط

لكل ربط أنواعه المدعومة الخاصة به؛ على سبيل المثال، يمكن استخدام سمة كائن ثنائي كبير الحجم مع معلمة سلسلة، أو معلمة POCO، أو CloudBlockBlobالمعلمة أو أي من الأنواع المدعومة العديدة الأخرى. تسرد المقالة المرجعية الربط لربطات الكائنات الثنائية كبيرة الحجم كافة أنواع المعلمات المعتمدة. لمزيد من المعلومات، راجع Triggers and bindings والمستندات المرجعية للارتباطات لكل نوع ارتباط.

تلميح

إذا كنت تخطط لاستخدام روابط HTTP أو WebHook، فخطط لتجنب استنفاد المنفذ الذي قد ينتج عن إنشاء مثيل غير صحيح لـ HttpClient. لمزيد من المعلومات، راجع كيفية إدارة الاتصالات في وظائف Azure.

الربط إلى قيمة إرجاع الأسلوب

يمكنك استخدام قيمة إرجاع أسلوب لربط إخراج، عن طريق تطبيق السمة على قيمة إرجاع الأسلوب. على سبيل المثال، راجع Triggers and bindings.

استخدم قيمة الإرجاع فقط إذا كان تنفيذ دالة ناجحة دوما ينتج قيمة إرجاع للتمرير إلى ربط الإخراج. وبخلاف ذلك، استخدم ICollector أو IAsyncCollector، كما هو موضح في القسم التالي.

كتابة قيم إخراج متعددة

لكتابة قيم متعددة إلى ارتباط إخراج، أو إذا كان استدعاء وظيفة ناجحة قد لا ينتج أي شيء لتمريره إلى ارتباط الإخراج، فاستخدم الأنواع ICollector أو IAsyncCollector. هذه الأنواع هي مجموعات للكتابة فقط تتم كتابتها إلى ربط الإخراج عند اكتمال الأسلوب.

يقوم هذا المثال بكتابة رسائل قائمة انتظار متعددة في قائمة الانتظار نفسها باستخدام ICollector:

public static class ICollectorExample
{
    [FunctionName("CopyQueueMessageICollector")]
    public static void Run(
        [QueueTrigger("myqueue-items-source-3")] string myQueueItem,
        [Queue("myqueue-items-destination")] ICollector<string> myDestinationQueue,
        ILogger log)
    {
        log.LogInformation($"C# function processed: {myQueueItem}");
        myDestinationQueue.Add($"Copy 1: {myQueueItem}");
        myDestinationQueue.Add($"Copy 2: {myQueueItem}");
    }
}

غير متزامنة

لجعل وظيفة غير متزامنة، استخدم الكلمة الأساسية async ثم قم بإرجاع كائن Task.

public static class AsyncExample
{
    [FunctionName("BlobCopy")]
    public static async Task RunAsync(
        [BlobTrigger("sample-images/{blobName}")] Stream blobInput,
        [Blob("sample-images-copies/{blobName}", FileAccess.Write)] Stream blobOutput,
        CancellationToken token,
        ILogger log)
    {
        log.LogInformation($"BlobCopy function processed.");
        await blobInput.CopyToAsync(blobOutput, 4096, token);
    }
}

لا يمكنك استخدام المعلمات out في الوظيفة غير المتزامنة. لارتباطات الإخراج، استخدم القيمة المرجعة للوظيفة أو كائن مجمع بدلاً من ذلك.

رموز الإلغاء المميزة

يمكن أن تقبل وظيفة معلمة CancellationToken، التي تمكن نظام التشغيل لإعلام التعليمات البرمجية الخاصة بك عندما تكون الوظيفة على وشك أن يتم إنهاؤها. يمكنك استخدام هذا الإعلام للتأكد من عدم إنهاء الوظيفة بشكل غير متوقع بطريقة تترك البيانات في حالة غير متناسقة.

ضع في اعتبارك الحالة عندما تكون لديك وظيفة تعالج الرسائل على دفعات. تعالج الدالة التالية المشغلة ناقل خدمة Azure صفيفا من كائنات ServiceBusReceivedMessage، والتي تمثل دفعة من الرسائل الواردة التي ستتم معالجتها عن طريق استدعاء دالة معينة:

using Azure.Messaging.ServiceBus;
using System.Threading;

namespace ServiceBusCancellationToken
{
    public static class servicebus
    {
        [FunctionName("servicebus")]
        public static void Run([ServiceBusTrigger("csharpguitar", Connection = "SB_CONN")]
               ServiceBusReceivedMessage[] messages, CancellationToken cancellationToken, ILogger log)
        {
            try
            { 
                foreach (var message in messages)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        log.LogInformation("A cancellation token was received. Taking precautionary actions.");
                        //Take precautions like noting how far along you are with processing the batch
                        log.LogInformation("Precautionary activities --complete--.");
                        break;
                    }
                    else
                    {
                        //business logic as usual
                        log.LogInformation($"Message: {message} was processed.");
                    }
                }
            }
            catch (Exception ex)
            {
                log.LogInformation($"Something unexpected happened: {ex.Message}");
            }
        }
    }
}

تسجيل الدخول

في التعليمات البرمجية للوظيفة الخاصة بك، يمكنك كتابة الإخراج إلى السجلات التي تظهر كتتبعات في تطبيق Insights. الطريقة الموصى بها للكتابة إلى السجلات هي تضمين معلمة من نوع ILogger، والتي تسمى عادة log . الإصدار 1.x من وقت تشغيل الوظائف المستخدمة TraceWriter،والذي يكتب أيضا إلى Application Insights ولكن لا يدعم تسجيل منظم. لا تستخدم Console.Write لكتابة السجلات الخاصة بك، حيث لا يتم التقاط هذه البيانات من قبل التطبيق Insights.

ILogger

في تعريف الدالة الخاص بك، قم بتضمين معلمة ILogger، التي تدعم التسجيل المنظم.

مع كائن ILogger يمكنك استدعاء Log<level>أساليب ملحق على ILogger لإنشاء سجلات. التعليمات البرمجية التالية تكتب Information سجلات مع الفئة Function.<YOUR_FUNCTION_NAME>.User. :

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, ILogger logger)
{
    logger.LogInformation("Request for item with key={itemKey}.", id);

لمعرفة المزيد حول كيفية تنفيذ الوظائف ILogger راجع تجميع بيانات القياس عن بعد. الفئات مسبوقة بافتراض Function أنك تستخدم مثيلا ILogger . إذا اخترت استخدام ILogger<T> بدلًا من ذلك، فقد يستند اسم الفئة بدلاً من ذلك إلى T.

تسجيل منظم

ترتيب العناصر النائبة، وليس أسمائهم، يحدد المعلمات المستخدمة في رسالة السجل. افترض أن لديك التعليمات البرمجية التالية:

string partitionKey = "partitionKey";
string rowKey = "rowKey";
logger.LogInformation("partitionKey={partitionKey}, rowKey={rowKey}", partitionKey, rowKey);

إذا كنت تحتفظ بنفس سلسلة الرسالة وعكس ترتيب المعلمات، فإن نص الرسالة الناتجة سيكون له القيم في الأماكن غير الصحيحة.

تتم معالجة العناصر النائبة بهذه الطريقة بحيث يمكنك القيام بتسجيل منظم. يخزن Application Insights أزواج المعامل والقيمة وسلسلة الرسالة. والنتيجة هي أن تصبح وسائط الرسالة حقول يمكنك الاستعلام عنها.

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

يمكنك أيضًا الاستعلام عن سلسلة الرسائل الأصلية عن طريق الرجوع إلى الحقل customDimensions.prop__{OriginalFormat}.

فيما يلي عينة تمثيل JSON customDimensions للبيانات:

{
  "customDimensions": {
    "prop__{OriginalFormat}":"C# Queue trigger function processed: {message}",
    "Category":"Function",
    "LogLevel":"Information",
    "prop__message":"c9519cbf-b1e6-4b9b-bf24-cb7d10b1bb89"
  }
}

تسجيل القياس عن بُعد المخصص

هناك إصدار خاص بالوظائف من Application Insights SDK يمكنك استخدامه لإرسال بيانات تتبع الاستخدام المخصصة من وظائفك إلى Application Insights: Microsoft.Azure.WebJobs.Logging.ApplicationInsights. استخدم الأمر التالي من موجه الأوامر لتثبيت هذه الحزمة:

dotnet add package Microsoft.Azure.WebJobs.Logging.ApplicationInsights --version <VERSION>

في هذا الأمر، استبدل <VERSION> بإصدار من هذه الحزمة التي تدعم الإصدار المثبت من Microsoft.Azure.WebJobs.

تستخدم أمثلة C # التالية واجهة برمجة تطبيقات القياس عن بُعد المخصصة. المثال هو لمكتبة فئة .NET ولكن التعليمات البرمجية لـ Application Insights هي نفسها بالنسبة للبرنامج النصي C#‎.

يستخدم الإصدار 2.x والإصدارات الأحدث من وقت التشغيل ميزات أحدث في Application Insights لربط التتبع عن بُعد بالعملية الحالية تلقائيًا. ليست هناك حاجة لضبط العملية أو الحقول Idأو ParentId أو Name يدويًا.

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
using System.Linq;

namespace functionapp0915
{
    public class HttpTrigger2
    {
        private readonly TelemetryClient telemetryClient;

        /// Using dependency injection will guarantee that you use the same configuration for telemetry collected automatically and manually.
        public HttpTrigger2(TelemetryConfiguration telemetryConfiguration)
        {
            this.telemetryClient = new TelemetryClient(telemetryConfiguration);
        }

        [FunctionName("HttpTrigger2")]
        public Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)]
            HttpRequest req, ExecutionContext context, ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");
            DateTime start = DateTime.UtcNow;

            // Parse query parameter
            string name = req.Query
                .FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
                .Value;

            // Write an event to the customEvents table.
            var evt = new EventTelemetry("Function called");
            evt.Context.User.Id = name;
            this.telemetryClient.TrackEvent(evt);

            // Generate a custom metric, in this case let's use ContentLength.
            this.telemetryClient.GetMetric("contentLength").TrackValue(req.ContentLength);

            // Log a custom dependency in the dependencies table.
            var dependency = new DependencyTelemetry
            {
                Name = "GET api/planets/1/",
                Target = "swapi.co",
                Data = "https://swapi.co/api/planets/1/",
                Timestamp = start,
                Duration = DateTime.UtcNow - start,
                Success = true
            };
            dependency.Context.User.Id = name;
            this.telemetryClient.TrackDependency(dependency);

            return Task.FromResult<IActionResult>(new OkResult());
        }
    }
}

في هذا المثال، يتم تجميع بيانات القياس المخصصة من قبل المضيف قبل إرسالها إلى جدول customMetrics. لمعرفة المزيد، راجع وثائق GetMetric في Application Insights.

عند التشغيل محليًا، يجب إضافة الإعداد APPINSIGHTS_INSTRUMENTATIONKEY، باستخدام مفتاح Application Insights، إلى ملف local.settings.json.

لا تتصل بـ TrackRequest أو StartOperation<RequestTelemetry> لأنك سترى طلبات مكررة لاستدعاء الوظائف. وقت تشغيل الدالات تلقائيًا بتعقب الطلبات.

لا تقم بتعيين telemetryClient.Context.Operation.Id. يتسبب هذا الإعداد العام في ارتباط غير صحيح عند تشغيل العديد من الوظائف في نفس الوقت. بدلاً من ذلك، قم بإنشاء مثيل جديد للقياس عن بعد (DependencyTelemetry و EventTelemetry) وتعديل الخاصية Context الخاصة به. ثم مرر مثيل القياس عن بعد إلى الأسلوب المطابق Track في TelemetryClient (TrackDependency() وTrackEvent() وTrackMetric()). تضمن هذه الطريقة أن القياس عن بعد يحتوي على تفاصيل الارتباط الصحيحة للاستحضار الدالة الحالية.

وظائف الاختبار

توضح المقالات التالية كيفية تشغيل وظيفة مكتبة فئة C # قيد المعالجة محليًا لأغراض الاختبار:

متغيرات البيئة

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

public static class EnvironmentVariablesExample
{
    [FunctionName("GetEnvironmentVariables")]
    public static void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log)
    {
        log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
        log.LogInformation(GetEnvironmentVariable("AzureWebJobsStorage"));
        log.LogInformation(GetEnvironmentVariable("WEBSITE_SITE_NAME"));
    }

    private static string GetEnvironmentVariable(string name)
    {
        return name + ": " +
            System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
    }
}

يمكن قراءة إعدادات التطبيق من متغيرات البيئة سواء عند التطوير محليًا أو عند التشغيل في Azure. عند التطوير محليًا، تأتي إعدادات التطبيق من Values المجموعة الموجودة في ملف local.settings.json. في كلا البيئتين، المحلية و Azure، يقوم GetEnvironmentVariable("<app setting name>") باسترداد قيمة إعداد التطبيق المسمى. على سبيل المثال، عند التشغيل محليًا، سيتم إرجاع "اسم الموقع الخاص بي" إذا كان ملف local.settings.json يحتوي على { "Values": { "WEBSITE_SITE_NAME": "My Site Name" } }.

خاصية urationManager.AppSettingsSystem.Configuration.Config هي واجهة برمجة تطبيقات بديلة للحصول على قيم إعداد التطبيق، ولكننا نوصي GetEnvironmentVariable باستخدامها كما هو موضح هنا.

الربط في وقت التشغيل

في C# ولغات .NET الأخرى، يمكنك استخدام نمط ربط إلزامي على عكس الربط في السمات التعريفية. الربط الحتمي مفيد عندما تحتاج معلمات الربط إلى حسابها في وقت التشغيل بدلاً من وقت التصميم. مع هذا النمط، يمكنك الربط إلى ارتباطات الإدخال والإخراج المدعومة في أثناء العمل في التعليمات البرمجية للوظيفة.

عرف الربط الحتمي كما يلي:

  • لا تقم بتضمين سمة في توقيع الدالة للارتباطات الحتمية التي ترغب بها.

  • قم بتمرير معلمة إدخال Binder binder أو IBinder binder.

  • استخدم نمط C#‎ التالي لتنفيذ ربط البيانات.

    using (var output = await binder.BindAsync<T>(new BindingTypeAttribute(...)))
    {
        ...
    }
    

    تُعد BindingTypeAttribute سمة .NET التي تعرف الربط الخاص بك ويُعد T نوع إدخال أو إخراج مدعوم من قِبل نوع الربط هذا. T لا يمكن أن يكون نوع معلمة out (مثل out JObject). على سبيل المثال، يدعم ربط إخراج جدول تطبيقات الأجهزة المحمولة ستة أنواع إخراج، ولكن لا يمكنك استخدام إلا ICollector<> أو IAsyncCollector< مع ربط إلزامي>.

مثال على السمة الفردية

يقوم مثال التعليمات البرمجية التالي بإنشاء ربط إخراج كائن تخزين ثنائي كبير الحجم مع مسار كائن ثنائي كبير الحجم تم تعريفه في وقت التشغيل، ثم يكتب سلسلة إلى الكائن الثنائي كبير الحجم.

public static class IBinderExample
{
    [FunctionName("CreateBlobUsingBinder")]
    public static void Run(
        [QueueTrigger("myqueue-items-source-4")] string myQueueItem,
        IBinder binder,
        ILogger log)
    {
        log.LogInformation($"CreateBlobUsingBinder function processed: {myQueueItem}");
        using (var writer = binder.Bind<TextWriter>(new BlobAttribute(
                    $"samples-output/{myQueueItem}", FileAccess.Write)))
        {
            writer.Write("Hello World!");
        };
    }
}

يُعرّف BlobAttribute ربط إدخال أو إخراج كائن التخزين الثنائي كبير الحجم، ويُعد TextWriter نوع ربط إخراج مدعومًا.

مثال سمات متعددة

يعمل المثال السابق على إعداد التطبيق لسلسلة اتصال حساب التخزين الرئيسي للتطبيق (وهو AzureWebJobsStorage). ويمكنك تحديد إعداد تطبيق مخصص لاستخدامه لحساب التخزين عن طريق إضافة StorageAccountAttribute وتمرير صفيف السمة إلى BindAsync<T>(). استخدم معلمةBinder وليس IBinder . على سبيل المثال:

public static class IBinderExampleMultipleAttributes
{
    [FunctionName("CreateBlobInDifferentStorageAccount")]
    public async static Task RunAsync(
            [QueueTrigger("myqueue-items-source-binder2")] string myQueueItem,
            Binder binder,
            ILogger log)
    {
        log.LogInformation($"CreateBlobInDifferentStorageAccount function processed: {myQueueItem}");
        var attributes = new Attribute[]
        {
        new BlobAttribute($"samples-output/{myQueueItem}", FileAccess.Write),
        new StorageAccountAttribute("MyStorageAccount")
        };
        using (var writer = await binder.BindAsync<TextWriter>(attributes))
        {
            await writer.WriteAsync("Hello World!!");
        }
    }
}

المشغلات وعمليات الربط

يعرض هذا الجدول الروابط المعتمدة في الإصدارات الرئيسية من وقت تشغيل Azure Functions:

نوع 1.x1 2.x وأعلى2 المشغِّل الإدخال الإخراج
Blob storage
Azure Cosmos DB
Azure Data Explorer
عنوان SQL لـ Azure
Dapr4
شبكة الأحداث
مراكز الأحداث
خطافات HTTP والويب
مركز IoT
Kafka3
تطبيقات الجوّال
مراكز الإعلامات
تخزين قائمة الانتظار
Redis
RabbitMQ3
SendGrid
ناقل الخدمة
SignalR
تخزين الجداول
المؤقت
Twilio

1سينتهي الدعم للإصدار 1.x من وقت تشغيل Azure Functions في 14 سبتمبر 2026. نوصي بشدة بترحيل تطبيقاتك إلى الإصدار 4.x للحصول على الدعم الكامل.

2 بدءا من وقت تشغيل الإصدار 2.x، يجب تسجيل جميع الروابط باستثناء HTTP وTimer. راجع تسجيل ملحقات الربط.

3 المشغلات غير مدعومة في خطة الاستهلاك. يتطلب مشغلات تستند إلى وقت التشغيل.

4 مدعوم فقط في Kubernetes وIoT Edge وغيرها من الأوضاع المستضافة ذاتيا فقط.

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