قم بتطوير وظائف مكتبة فئة 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.x1 | .NET 9.0 (معاينة) .NET 8.0 .NET 6.02 .NET Framework 4.83 |
.NET 8.0 .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.
التحديث إلى الهدف .NET 8
يمكن للتطبيقات التي تستخدم النموذج قيد المعالجة استهداف .NET 8 باتباع الخطوات الموضحة في هذا القسم. ومع ذلك، إذا اخترت ممارسة هذا الخيار، فلا يزال يتعين عليك البدء في التخطيط للترحيل إلى نموذج العامل المعزول قبل انتهاء الدعم للنموذج قيد المعالجة في 10 نوفمبر 2026.
يمكن للعديد من التطبيقات تغيير تكوين تطبيق الوظائف في Azure دون تحديثات للتعليمات البرمجية أو إعادة التوزيع. لتشغيل .NET 8 مع النموذج قيد المعالجة، يلزم إجراء ثلاثة تكوينات:
- يجب تعيين إعداد
FUNCTIONS_WORKER_RUNTIME
التطبيق بالقيمة "dotnet". - يجب تعيين إعداد
FUNCTIONS_EXTENSION_VERSION
التطبيق بالقيمة "~4". - يجب تعيين إعداد
FUNCTIONS_INPROC_NET8_ENABLED
التطبيق بالقيمة "1". - يجب تحديث تكوين المكدس للإشارة إلى .NET 8.
لا يزال دعم .NET 8 يستخدم الإصدار 4.x من وقت تشغيل الوظائف، ولا يلزم إجراء أي تغيير على إصدار وقت التشغيل المكون.
لتحديث مشروعك المحلي، تأكد أولا من استخدام أحدث إصدارات الأدوات المحلية. ثم تأكد من أن المشروع يشير إلى الإصدار 4.4.0 أو أحدث من Microsoft.NET.Sdk.Functions. يمكنك بعد ذلك تغيير إلى TargetFramework
"net8.0". يجب عليك أيضا التحديث local.settings.json
لتضمين كل من FUNCTIONS_WORKER_RUNTIME
تعيين إلى "dotnet" وتعيين FUNCTIONS_INPROC_NET8_ENABLED
إلى "1".
فيما يلي مثال على ملف الحد الأدنى project
مع هذه التغييرات:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.4.0" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>
فيما يلي مثال على ملف الحد الأدنى local.settings.json
مع هذه التغييرات:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_INPROC_NET8_ENABLED": "1",
"FUNCTIONS_WORKER_RUNTIME": "dotnet"
}
}
إذا كان تطبيقك يستخدم Microsoft.Azure.DurableTask.Netherite.AzureFunctions
، فتأكد من أنه يستهدف الإصدار 1.5.3 أو أحدث. نظرا لتغيير السلوك في .NET 8، ستطرح التطبيقات ذات الإصدارات القديمة من الحزمة استثناء منشئ غامض.
قد تحتاج إلى إجراء تغييرات أخرى على تطبيقك استنادا إلى دعم الإصدار لتبعياته الأخرى.
يوفر الإصدار 4.x من وقت تشغيل الوظائف وظائف مكافئة ل .NET 6 و.NET 8. لا يتضمن النموذج قيد المعالجة ميزات أو تحديثات إضافية تتكامل مع قدرات .NET 8 الجديدة. على سبيل المثال، لا يدعم وقت التشغيل الخدمات الرئيسية. للاستفادة الكاملة من أحدث قدرات وتحسينات .NET 8، يجب الترحيل إلى نموذج العامل المعزول.
مشروع مكتبة فئة الوظائف
في 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
المعلمة.
معلمات توقيع الأسلوب
قد يحتوي توقيع الأسلوب على معلمات أخرى غير تلك المستخدمة مع سمة المشغل. فيما يلي بعض المعلمات الأخرى التي يمكنك تضمينها:
- ربطات الإدخال والإخراج التي تم وضع علامة عليها على هذا النحو عن طريق تزيينها بالسمات.
ILogger
أوTraceWriter
( الإصدار1.x فقط) للتسجيلللمعلمة.CancellationToken
معلمة ل إيقاف التشغيل بأمان.- ربط التعبيرات معلمات للحصول على بيانات تعريف المشغل.
ترتيب المعلمات في توقيع الوظيفة لا يهم. على سبيل المثال، يمكنك وضع معلمات المشغل قبل أو بعد الارتباطات الأخرى، ويمكنك وضع معلمة المسجل قبل أو بعد مشغل أو معلمات الربط.
روابط الإخراج
يمكن أن تحتوي الدالة على صفر أو روابط إخراج متعددة معرفة باستخدام معلمات الإخراج.
المثال التالي يعدل السابق بإضافة ربط قائمة انتظار إخراج مسمى 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>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.5.0" />
</ItemGroup>
هام
بدءا من الإصدار 4.0.6517 من Core Tools، يجب أن تشير مشاريع النموذج قيد المعالجة إلى الإصدار 4.5.0 أو أحدث من Microsoft.NET.Sdk.Functions
. إذا تم استخدام إصدار سابق، func start
فسيخطأ الأمر.
بين 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>net8.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.x من وقت تشغيل Azure Functions في 14 سبتمبر 2026. نوصي بشدة بترحيل تطبيقاتك إلى الإصدار 4.x للحصول على الدعم الكامل.
- بدءا من وقت تشغيل الإصدار 2.x، يجب تسجيل جميع الروابط باستثناء HTTP وTimer. راجع تسجيل ملحقات الربط.
- المشغلات غير مدعومة في خطة الاستهلاك. يتطلب مشغلات تستند إلى وقت التشغيل.
- مدعوم في Kubernetes وIoT Edge وغيرها من الأوضاع المستضافة ذاتيا فقط.