دليل لتشغيل وظائف C# Azure في نموذج العامل المعزول

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

استخدم الارتباطات التالية للبدء مباشرة في إنشاء وظائف نموذج عامل .NET المعزولة.

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

لمعرفة المزيد حول نشر مشروع نموذج عامل معزول إلى Azure، راجع التوزيع إلى Azure Functions.

فوائد نموذج العامل المعزول

هناك وضعان يمكنك منهما تشغيل وظائف مكتبة فئة .NET: إما في نفس العملية مثل وقت تشغيل مضيف الوظائف (قيد المعالجة) أو في عملية عامل معزولة. عند تشغيل وظائف .NET في عملية عامل معزولة، يمكنك الاستفادة من المزايا التالية:

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

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

للحصول على مقارنة شاملة بين الوضعين، راجع الاختلافات بين العملية قيد المعالجة وعزل عملية العامل .NET Azure Functions.

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

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

إشعار

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

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

إصدار وقت تشغيل الوظائف نموذج عامل معزول النموذجقيد المعالجة 4
الدالات 4.x1 .NET 9.0
.NET 8.0
.NET Framework 4.82
.NET 8.0
الدالات 1.x3 غير متوفر .NET Framework 4.8

1 .NET 6 كان مدعوما مسبقا على كلا النموذجين ولكنه وصل إلى نهاية الدعم الرسمي في 12 نوفمبر 2024. تم دعم .NET 7 مسبقا على نموذج العامل المعزول ولكنه وصل إلى نهاية الدعم الرسمي في 14 مايو 2024.

2 تتطلب عملية الإنشاء أيضا .NET SDK.

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

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

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

بنية المشروع

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

  • ملف مشروع C# (.csproj) يحدد المشروع والتبعيات.
  • ملف Program.cs الذي يمثل نقطة الدخول للتطبيق.
  • أي ملفات تعليمات برمجية تحدد وظائفك.
  • host.json الملف الذي يحدد التكوين المشترك بين الوظائف في مشروعك.
  • local.settings.json الملف الذي يحدد متغيرات البيئة التي يستخدمها مشروعك عند تشغيله محليا على جهازك.

للحصول على أمثلة كاملة، راجع نموذج مشروع .NET 8 ومشروع نموذج .NET Framework 4.8.

مراجع الحزمة

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

حزم الذاكرة الأساسية

الحزم التالية مطلوبة لتشغيل وظائف .NET في عملية عامل معزولة:

الإصدار 2.x

تعمل إصدارات 2.x من الحزم الأساسية على تغيير أطر العمل المدعومة وتقديم الدعم لواجهات برمجة تطبيقات .NET الجديدة من هذه الإصدارات الأحدث. عند استهداف .NET 9 أو إصدار أحدث، يحتاج تطبيقك إلى الرجوع إلى الإصدار 2.0.0 أو أحدث من كلتا الحزمتين.

عند التحديث إلى إصدارات 2.x، لاحظ التغييرات التالية:

  • بدءا من الإصدار 2.0.0 من Microsoft.Azure.Functions.Worker.Sdk:
  • بدءا من الإصدار 2.0.0 من Microsoft.Azure.Functions.Worker:
    • يضيف هذا الإصدار دعما ل IHostApplicationBuilder. تتضمن بعض الأمثلة في هذا الدليل علامات تبويب لإظهار البدائل باستخدام IHostApplicationBuilder. تتطلب هذه الأمثلة إصدارات 2.x.
    • يتم تضمين التحقق من صحة نطاق موفر الخدمة بشكل افتراضي إذا تم تشغيله في بيئة تطوير. يطابق هذا السلوك ASP.NET Core.
    • EnableUserCodeException يتم تمكين الخيار بشكل افتراضي. تم وضع علامة على الخاصية الآن على أنها قديمة.
    • IncludeEmptyEntriesInMessagePayload يتم تمكين الخيار بشكل افتراضي. مع تمكين هذا الخيار، يتضمن تشغيل الحمولات التي تمثل المجموعات دائما إدخالات فارغة. على سبيل المثال، إذا تم إرسال رسالة بدون نص أساسي، فسيظل الإدخال الفارغ موجودا لبيانات string[] المشغل. يسهل تضمين الإدخالات الفارغة الرجوع المتقاطع مع صفائف بيانات التعريف التي قد تشير إليها الدالة أيضا. يمكنك تعطيل هذا السلوك عن طريق الإعداد IncludeEmptyEntriesInMessagePayload إلى false في WorkerOptions تكوين الخدمة.
    • ILoggerExtensions تتم إعادة تسمية الفئة إلى FunctionsLoggerExtensions. تمنع إعادة التسمية خطأ مكالمة غامضة عند استخدام LogMetric() على مثيل ILogger .
    • بالنسبة للتطبيقات التي تستخدم HttpResponseData، WriteAsJsonAsync() لن يقوم الأسلوب بعد الآن بتعيين رمز الحالة إلى 200 OK. في 1.x، يؤدي هذا إلى تجاوز رموز الخطأ الأخرى التي تم تعيينها.
  • تسقط إصدارات 2.x دعم .NET 5 TFM.

الحزم الملحقة

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

يمكنك العثور على حزم الملحقات هذه ضمن Microsoft.Azure.Functions.Worker.Extensions.

بدء التشغيل والتكوين

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

تعرض التعليمات البرمجية التالية مثالا على مسار HostBuilder :

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(s =>
    {
        s.AddApplicationInsightsTelemetryWorkerService();
        s.ConfigureFunctionsApplicationInsights();
        s.AddSingleton<IHttpResponderService, DefaultHttpResponderService>();
        s.Configure<LoggerFilterOptions>(options =>
        {
            // The Application Insights SDK adds a default logging filter that instructs ILogger to capture only Warning and more severe logs. Application Insights requires an explicit override.
            // Log levels can also be configured using appsettings.json. For more information, see https://learn.microsoft.com/en-us/azure/azure-monitor/app/worker-service#ilogger-logs
            LoggerFilterRule? toRemove = options.Rules.FirstOrDefault(rule => rule.ProviderName
                == "Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider");

            if (toRemove is not null)
            {
                options.Rules.Remove(toRemove);
            }
        });
    })
    .Build();

تتطلب هذه التعليمة البرمجية using Microsoft.Extensions.DependencyInjection;.

قبل الاتصال Build() على IHostBuilder، يجب عليك:

  • اتصل إما ConfigureFunctionsWebApplication() إذا كنت تستخدم تكامل ASP.NET Core أو ConfigureFunctionsWorkerDefaults() غير ذلك. راجع مشغل HTTP للحصول على تفاصيل حول هذه الخيارات.
    إذا كنت تكتب التطبيق الخاص بك باستخدام F#، تتطلب بعض ملحقات المشغل والربط تكوينا إضافيا. راجع وثائق الإعداد لملحق Blobs وملحق الجداول وملحق Cosmos DB عندما تخطط لاستخدام هذه الملحقات في تطبيق F#‎.
  • تكوين أي خدمات أو تكوين تطبيق يتطلبه مشروعك. راجع التكوين للحصول على التفاصيل.
    إذا كنت تخطط لاستخدام Application Insights، فستحتاج إلى الاتصال AddApplicationInsightsTelemetryWorkerService() بالمفوض وفيه ConfigureFunctionsApplicationInsights() ConfigureServices() . راجع Application Insights للحصول على التفاصيل.

إذا كان مشروعك يستهدف .NET Framework 4.8، فأنت بحاجة أيضًا إلى إضافة FunctionsDebugger.Enable(); قبل إنشاء HostBuilder. يجب أن يكون السطر الأول من أسلوب Main() الخاص بك. لمزيد من المعلومات، راجع تصحيح الأخطاء عند استهداف .NET Framework.

يتم استخدام HostBuilder لإنشاء مثيل تمت تهيئته IHost بالكامل وإرجاعه، والذي تقوم بتشغيله بشكل غير متزامن لبدء تشغيل تطبيق الوظائف.

await host.RunAsync();

التكوين

يحدد نوع المنشئ الذي تستخدمه كيفية تكوين التطبيق.

يتم استخدام أسلوب ConfigureFunctionsWorkerDefaults لإضافة الإعدادات المطلوبة لتشغيل تطبيق الوظائف. يتضمن الأسلوب الوظائف التالية:

  • مجموعة المحولات الافتراضية.
  • تعيين JsonSerializerOptions الافتراضي لتجاهل الغلاف على أسماء الخصائص.
  • التكامل مع تسجيل Azure Functions.
  • إخراج ربط البرامج الوسيطة والميزات.
  • وظيفة تنفيذ البرامج الوسيطة.
  • دعم gRPC الافتراضي.
.ConfigureFunctionsWorkerDefaults()

يعني الوصول إلى مسار منشئ المضيف أنه يمكنك أيضًا تعيين أي تكوينات خاصة بالتطبيق أثناء التهيئة. يمكنك استدعاء أسلوب ConfigureAppConfiguration على HostBuilder مرة واحدة أو أكثر لإضافة أي مصادر تكوين مطلوبة بواسطة التعليمات البرمجية الخاصة بك. لمعرفة المزيد حول تكوين التطبيق، راجع التكوين في ASP.NET Core.

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

إشعار

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

إدراج التبعية

يستخدم نموذج العامل المعزول آليات .NET القياسية لحقن الخدمات.

عند استخدام HostBuilder، اتصل ب ConfigureServices على منشئ المضيف واستخدم أساليب الامتداد على IServiceCollection لإدخال خدمات معينة. يضيف المثال التالي تبعية خدمة فردية:

.ConfigureServices(services =>
{
    services.AddSingleton<IHttpResponderService, DefaultHttpResponderService>();
})

تتطلب هذه التعليمة البرمجية using Microsoft.Extensions.DependencyInjection;. لمعرفة المزيد، راجع إدخال التبعية في ASP.NET Core.

تسجيل عملاء Azure

يمكن استخدام إدخال التبعية للتفاعل مع خدمات Azure الأخرى. يمكنك إدخال العملاء من Azure SDK ل .NET باستخدام حزمة Microsoft.Extensions.Azure . بعد تثبيت الحزمة، قم بتسجيل العملاء عن طريق الاتصال AddAzureClients() على مجموعة الخدمة في Program.cs. يقوم المثال التالي بتكوين عميل مسمى ل Azure Blobs:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices((hostContext, services) =>
    {
        services.AddAzureClients(clientBuilder =>
        {
            clientBuilder.AddBlobServiceClient(hostContext.Configuration.GetSection("MyStorageConnection"))
                .WithName("copierOutputBlob");
        });
    })
    .Build();

host.Run();

يوضح المثال التالي كيف يمكننا استخدام هذا التسجيل وأنواع SDK لنسخ محتويات كائن ثنائي كبير الحجم كتدفق من حاوية إلى أخرى باستخدام عميل تم إدخاله:

using Microsoft.Extensions.Azure;
using Microsoft.Extensions.Logging;

namespace MyFunctionApp
{
    public class BlobCopier
    {
        private readonly ILogger<BlobCopier> _logger;
        private readonly BlobContainerClient _copyContainerClient;

        public BlobCopier(ILogger<BlobCopier> logger, IAzureClientFactory<BlobServiceClient> blobClientFactory)
        {
            _logger = logger;
            _copyContainerClient = blobClientFactory.CreateClient("copierOutputBlob").GetBlobContainerClient("samples-workitems-copy");
            _copyContainerClient.CreateIfNotExists();
        }

        [Function("BlobCopier")]
        public async Task Run([BlobTrigger("samples-workitems/{name}", Connection = "MyStorageConnection")] Stream myBlob, string name)
        {
            await _copyContainerClient.UploadBlobAsync(name, myBlob);
            _logger.LogInformation($"Blob {name} copied!");
        }

    }
}

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

تلميح

استخدم المثال سلسلة حرفية لاسم العميل في كل Program.cs من الدالة و. ضع في اعتبارك بدلا من ذلك استخدام سلسلة ثابتة مشتركة محددة في فئة الدالة. على سبيل المثال، يمكنك إضافة public const string CopyStorageClientName = nameof(_copyContainerClient); ثم الرجوع BlobCopier.CopyStorageClientName في كلا الموقعين. يمكنك بالمثل تعريف اسم قسم التكوين باستخدام الدالة بدلا من في Program.cs.

البرامج الوسيطة

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

يحتوي أسلوب ملحق ConfigureFunctionsWorkerDefaults على حمولة زائدة تتيح لك تسجيل البرامج الوسيطة الخاصة بك، كما ترى في المثال التالي.

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults(workerApplication =>
    {
        // Register our custom middlewares with the worker

        workerApplication.UseMiddleware<ExceptionHandlingMiddleware>();

        workerApplication.UseMiddleware<MyCustomMiddleware>();

        workerApplication.UseWhen<StampHttpHeaderMiddleware>((context) =>
        {
            // We want to use this middleware only for http trigger invocations.
            return context.FunctionDefinition.InputBindings.Values
                          .First(a => a.Type.EndsWith("Trigger")).Type == "httpTrigger";
        });
    })
    .Build();

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

تسهل أساليب التوسيع التالية على FunctionContext العمل مع البرمجيات الوسيطة في النموذج المعزول.

الطريقة ‏‏الوصف
GetHttpRequestDataAsync يحصل على مثيل HttpRequestData عند استدعاؤه بواسطة مشغل HTTP. يرجع هذا الأسلوب مثيل ValueTask<HttpRequestData?>، وهو مفيد عندما تريد قراءة بيانات الرسالة، مثل عناوين الطلبات وملفات تعريف الارتباط.
GetHttpResponseData يحصل على مثيل HttpResponseData عند استدعاؤه بواسطة مشغل HTTP.
GetInvocationResult يحصل على مثيل InvocationResult، والذي يمثل نتيجة تنفيذ الوظيفة الحالية. استخدم الخاصية Value للحصول على القيمة أو تعيينها حسب الحاجة.
GetOutputBindings يحصل على إدخالات ربط الإخراج لتنفيذ الوظيفة الحالية. كل إدخال في نتيجة هذا الأسلوب من النوع OutputBindingData. يمكنك استخدام الخاصية Value للحصول على القيمة أو تعيينها حسب الحاجة.
BindInputAsync يربط عنصر ربط الإدخال لمثيل BindingMetadata المطلوب. على سبيل المثال، يمكنك استخدام هذا الأسلوب عندما يكون لديك دالة BlobInput مع ربط إدخال يحتاج إلى استخدامه من قبل البرنامج الوسيط الخاص بك.

هذا مثال على تنفيذ برنامج وسيط يقرأ المثيل HttpRequestData ويحدث المثيل HttpResponseData أثناء تنفيذ الدالة:

internal sealed class StampHttpHeaderMiddleware : IFunctionsWorkerMiddleware
{
    public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
    {
        var requestData = await context.GetHttpRequestDataAsync();

        string correlationId;
        if (requestData!.Headers.TryGetValues("x-correlationId", out var values))
        {
            correlationId = values.First();
        }
        else
        {
            correlationId = Guid.NewGuid().ToString();
        }

        await next(context);

        context.GetHttpResponseData()?.Headers.Add("x-correlationId", correlationId);
    }
}

يتحقق هذا البرنامج الوسيط من وجود عنوان طلب محدد (x-correlationId)، وعند وجوده يستخدم قيمة العنوان لختم عنوان استجابة. خلاف ذلك، فإنه يولد قيمة GUID جديدة ويستخدمها لختم عنوان الاستجابة. للحصول على مثال أكثر اكتمالا لاستخدام برنامج وسيط مخصص في تطبيق الوظائف، راجع نموذج مرجع البرامج الوسيطة المخصصة.

تخصيص تسلسل JSON

يستخدم System.Text.Json نموذج العامل المعزول بشكل افتراضي. يمكنك تخصيص سلوك المحول التسلسلي عن طريق تكوين الخدمات كجزء من ملفك Program.cs . يغطي هذا القسم التسلسل للأغراض العامة ولن يؤثر على تسلسل JSON لمشغل HTTP مع تكامل ASP.NET Core، والذي يجب تكوينه بشكل منفصل.

يوضح المثال التالي هذا باستخدام ConfigureFunctionsWebApplication، ولكنه سيعمل أيضا مع ConfigureFunctionsWorkerDefaults:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication((IFunctionsWorkerApplicationBuilder builder) =>
    {
        builder.Services.Configure<JsonSerializerOptions>(jsonSerializerOptions =>
        {
            jsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
            jsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
            jsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;

            // override the default value
            jsonSerializerOptions.PropertyNameCaseInsensitive = false;
        });
    })
    .Build();

host.Run();

قد تحتاج بدلا من ذلك إلى استخدام JSON.NET (Newtonsoft.Json) للتسلسل. للقيام بذلك، يمكنك تثبيت الحزمة Microsoft.Azure.Core.NewtonsoftJson . ثم، في تسجيل الخدمة، يمكنك إعادة تعيين الخاصية Serializer على WorkerOptions التكوين. يوضح المثال التالي هذا باستخدام ConfigureFunctionsWebApplication، ولكنه سيعمل أيضا مع ConfigureFunctionsWorkerDefaults:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication((IFunctionsWorkerApplicationBuilder builder) =>
    {
        builder.Services.Configure<WorkerOptions>(workerOptions =>
        {
            var settings = NewtonsoftJsonObjectSerializer.CreateJsonSerializerSettings();
            settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            settings.NullValueHandling = NullValueHandling.Ignore;

            workerOptions.Serializer = new NewtonsoftJsonObjectSerializer(settings);
        });
    })
    .Build();

host.Run();

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

أسلوب الدالة هو أسلوب عام لفئة عامة مع سمة Function مطبقة على الأسلوب وسمة مشغل مطبقة على معلمة إدخال، كما هو موضح في المثال التالي:

[Function(nameof(QueueFunction))]
[QueueOutput("output-queue")]
public string[] Run([QueueTrigger("input-queue")] Album myQueueItem, FunctionContext context)

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

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

معلمات الوظيفة

فيما يلي بعض المعلمات التي يمكنك تضمينها كجزء من توقيع أسلوب الدالة:

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

سياق التنفيذ

يقوم .NET المعزول بتمرير كائن FunctionContext إلى أساليب الدالة الخاصة بك. يتيح لك هذا الكائن الحصول على مثيل ILogger للكتابة إلى السجلات عن طريق استدعاء أسلوب GetLogger وتوفير سلسلة categoryName . يمكنك استخدام هذا السياق للحصول على ILogger دون الحاجة إلى استخدام إدخال التبعية. لمعرفة المزيد، راجع التسجيل.

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

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

يتم دعم رموز الإلغاء المميزة في وظائف .NET عند التشغيل في عملية عامل معزولة. يطرح المثال التالي استثناء عند تلقي طلب إلغاء:

[Function(nameof(ThrowOnCancellation))]
public async Task ThrowOnCancellation(
    [EventHubTrigger("sample-workitem-1", Connection = "EventHubConnection")] string[] messages,
    FunctionContext context,
    CancellationToken cancellationToken)
{
    _logger.LogInformation("C# EventHub {functionName} trigger function processing a request.", nameof(ThrowOnCancellation));

    foreach (var message in messages)
    {
        cancellationToken.ThrowIfCancellationRequested();
        await Task.Delay(6000); // task delay to simulate message processing
        _logger.LogInformation("Message '{msg}' was processed.", message);
    }
}

يقوم المثال التالي بتنفيذ إجراءات التنظيف عند تلقي طلب إلغاء:

[Function(nameof(HandleCancellationCleanup))]
public async Task HandleCancellationCleanup(
    [EventHubTrigger("sample-workitem-2", Connection = "EventHubConnection")] string[] messages,
    FunctionContext context,
    CancellationToken cancellationToken)
{
    _logger.LogInformation("C# EventHub {functionName} trigger function processing a request.", nameof(HandleCancellationCleanup));

    foreach (var message in messages)
    {
        if (cancellationToken.IsCancellationRequested)
        {
            _logger.LogInformation("A cancellation token was received, taking precautionary actions.");
            // Take precautions like noting how far along you are with processing the batch
            _logger.LogInformation("Precautionary activities complete.");
            break;
        }

        await Task.Delay(6000); // task delay to simulate message processing
        _logger.LogInformation("Message '{msg}' was processed.", message);
    }
}

Bindings

يتم تعريف الارتباطات باستخدام السمات الخاصة بالطرق، والمعلمات، وأنواع الإرجاع. يمكن أن توفر الروابط البيانات كسلاسل وصفائف وأنواع قابلة للتسلسل، مثل كائنات الفئة القديمة العادية (POCOs). بالنسبة لبعض ملحقات الربط، يمكنك أيضا الربط بالأنواع الخاصة بالخدمة المحددة في حزم SDK للخدمة.

بالنسبة إلى مشغلات HTTP، راجع قسم مشغل HTTP.

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

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

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

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

للكتابة إلى ربط إخراج، يجب تطبيق سمة ربط الإخراج على أسلوب الدالة، الذي يحدد كيفية الكتابة إلى الخدمة المرتبطة. تتم كتابة القيمة التي تم إرجاعها من خلال الأسلوب إلى ربط الإخراج. على سبيل المثال، يكتب المثال التالي قيمة سلسلة إلى قائمة انتظار رسائل تسمى output-queue باستخدام ربط إخراج:

[Function(nameof(QueueFunction))]
[QueueOutput("output-queue")]
public string[] Run([QueueTrigger("input-queue")] Album myQueueItem, FunctionContext context)
{
    // Use a string array to return more than one message.
    string[] messages = {
        $"Album name = {myQueueItem.Name}",
        $"Album songs = {myQueueItem.Songs}"};

    _logger.LogInformation("{msg1},{msg2}", messages[0], messages[1]);

    // Queue Output messages
    return messages;
}

روابط إخراج متعددة

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

public class MultipleOutputBindings
{
    private readonly ILogger<MultipleOutputBindings> _logger;

    public MultipleOutputBindings(ILogger<MultipleOutputBindings> logger)
    {
        _logger = logger;
    }

    [Function("MultipleOutputBindings")]
    public MyOutputType Run([HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req)
    {
        _logger.LogInformation("C# HTTP trigger function processed a request.");
        var myObject = new MyOutputType
        {
            Result = new OkObjectResult("C# HTTP trigger function processed a request."),
            MessageText = "some output"
        };
        return myObject;
    }

    public class MyOutputType
    {
        [HttpResult]
        public IActionResult Result { get; set; }

        [QueueOutput("myQueue")]
        public string MessageText { get; set; }
    }
}

عند استخدام أنواع الإرجاع المخصصة لروابط إخراج متعددة مع تكامل ASP.NET Core، يجب إضافة السمة [HttpResult] إلى الخاصية التي توفر النتيجة. HttpResult تتوفر السمة عند استخدام SDK 1.17.3-preview2 أو أحدث مع الإصدار 3.2.0 أو أحدث من ملحق HTTP والإصدار 1.3.0 أو أحدث من ملحق ASP.NET Core.

أنواع SDK

بالنسبة لبعض أنواع الربط الخاصة بالخدمة، يمكن توفير بيانات الربط باستخدام أنواع من حزم SDK وأطر العمل للخدمة. توفر هذه إمكانية أكبر تتجاوز ما يمكن أن تقدمه السلسلة المتسلسلة أو كائن CLR القديم العادي (POCO). لاستخدام الأنواع الأحدث، يجب تحديث مشروعك لاستخدام إصدارات أحدث من التبعيات الأساسية.

Dependency متطلبات الإصدار
Microsoft.Azure.Functions.Worker 1.18.0 أو أحدث
Microsoft.Azure.Functions.Worker.Sdk 1.13.0 أو أحدث

عند اختبار أنواع SDK محليا على جهازك، تحتاج أيضا إلى استخدام Azure Functions Core Tools، الإصدار 4.0.5000 أو أحدث. يمكنك التحقق من الإصدار الحالي باستخدام func version الأمر .

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

الخدمة المشغِّل ربط بيانات الإدخال ربط بيانات الإخراج
Azure Blobs متوفر بشكل عام متوفر بشكل عام أنواع SDK غير مستحسنة.1
قوائم انتظار Azure متوفر بشكل عام ربط الإدخال غير موجود أنواع SDK غير مستحسنة.1
ناقل خدمة Azure متوفر بشكل عام ربط الإدخال غير موجود أنواع SDK غير مستحسنة.1
مراكز أحداث Azure متوفر بشكل عام ربط الإدخال غير موجود أنواع SDK غير مستحسنة.1
Azure Cosmos DB أنواع SDK غير مستخدمة2 متوفر بشكل عام أنواع SDK غير مستحسنة.1
جداول Azure المشغل غير موجود متوفر بشكل عام أنواع SDK غير مستحسنة.1
Azure Event Grid متوفر بشكل عام ربط الإدخال غير موجود أنواع SDK غير مستحسنة.1

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

2 يستخدم مشغل Cosmos DB موجز تغيير Azure Cosmos DB ويعرض عناصر موجز التغيير لأنواع JSON القابلة للتسلسل. يعد عدم وجود أنواع SDK حسب التصميم لهذا السيناريو.

إشعار

عند استخدام تعبيرات الربط التي تعتمد على بيانات المشغل، لا يمكن استخدام أنواع SDK للمشغل نفسه.

مشغل HTTP

تسمح مشغلات HTTP باستدعاء دالة بواسطة طلب HTTP. هناك نهجان مختلفان يمكن استخدامهما:

  • نموذج تكامل ASP.NET Core يستخدم مفاهيم مألوفة ASP.NET مطوري Core
  • نموذج مضمن، والذي لا يتطلب تبعيات إضافية ويستخدم أنواعا مخصصة لطلبات واستجابات HTTP. يتم الاحتفاظ بهذا الأسلوب للتوافق مع الإصدارات السابقة مع تطبيقات العامل المعزولة ل .NET.

تكامل ASP.NET Core

يوضح هذا القسم كيفية العمل مع طلب HTTP الأساسي وعناصر الاستجابة باستخدام أنواع من ASP.NET Core بما في ذلك HttpRequest وHttpResponse وIActionResult. هذا النموذج غير متوفر للتطبيقات التي تستهدف .NET Framework، والتي يجب أن تستخدم النموذج المضمن بدلا من ذلك.

إشعار

لا يتعرض هذا النموذج لجميع ميزات ASP.NET Core. على وجه التحديد، لا تتوفر البنية الأساسية لبرنامج ربط العمليات التجارية لبرنامج ربط العمليات التجارية الأساسية ASP.NET وقدرات التوجيه. يتطلب تكامل ASP.NET Core استخدام الحزم المحدثة.

لتمكين تكامل ASP.NET Core ل HTTP:

  1. أضف مرجعا في مشروعك إلى حزمة Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore ، الإصدار 1.0.0 أو أحدث.

  2. قم بتحديث مشروعك لاستخدام إصدارات الحزمة المحددة هذه:

  3. في ملفك Program.cs ، قم بتحديث تكوين منشئ المضيف لاستدعاء ConfigureFunctionsWebApplication(). يستبدل ConfigureFunctionsWorkerDefaults() هذا إذا كنت ستستخدم هذا الأسلوب بخلاف ذلك. يوضح المثال التالي الحد الأدنى من الإعداد دون تخصيصات أخرى:

    using Microsoft.Azure.Functions.Worker;
    using Microsoft.Extensions.Hosting;
    
    var host = new HostBuilder()
        .ConfigureFunctionsWebApplication()
        .Build();
    
    host.Run();
    
  4. قم بتحديث أي وظائف موجودة يتم تشغيلها من قبل HTTP لاستخدام أنواع ASP.NET Core. يوضح هذا المثال المعيار HttpRequest والمستخدم IActionResult لوظيفة بسيطة "hello, world":

    [Function("HttpFunction")]
    public IActionResult Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req)
    {
        return new OkObjectResult($"Welcome to Azure Functions, {req.Query["name"]}!");
    }
    

تسلسل JSON مع تكامل ASP.NET Core

ASP.NET Core له طبقة التسلسل الخاصة به، ولا يتأثر بتخصيص تكوين التسلسل العام. لتخصيص سلوك التسلسل المستخدم لمشغلات HTTP، تحتاج إلى تضمين .AddMvc() مكالمة كجزء من تسجيل الخدمة. يمكن استخدام الذي تم إرجاعه IMvcBuilder لتعديل إعدادات تسلسل JSON ASP.NET Core.

يمكنك الاستمرار في استخدام HttpRequestData وأثناء HttpResponsedata استخدام تكامل ASP.NET، على الرغم من أنه بالنسبة لمعظم التطبيقات، من الأفضل استخدام HttpRequest و IActionResultبدلا من ذلك. لا يستدعي استخدام HttpRequestData/HttpResponseData طبقة التسلسل ASP.NET Core ويعتمد بدلا من ذلك على تكوين تسلسل العامل العام للتطبيق. ومع ذلك، عند تمكين تكامل ASP.NET Core، قد لا تزال بحاجة إلى إضافة تكوين. السلوك الافتراضي من ASP.NET Core هو عدم السماح ب IO المتزامن. لاستخدام مسلسل مخصص لا يدعم IO غير المتزامن، مثل NewtonsoftJsonObjectSerializer، تحتاج إلى تمكين IO المتزامن للتطبيق الخاص بك عن طريق تكوين KestrelServerOptions.

يوضح المثال التالي كيفية تكوين JSON.NET (Newtonsoft.Json) وحزمة Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet للتسلسل باستخدام هذا الأسلوب:

using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureServices(services =>
    {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
        services.AddMvc().AddNewtonsoftJson();

        // Only needed if using HttpRequestData/HttpResponseData and a serializer that doesn't support asynchronous IO
        // services.Configure<KestrelServerOptions>(options => options.AllowSynchronousIO = true);
    })
    .Build();
host.Run();

نموذج HTTP المضمن

في النموذج المضمن، يترجم النظام رسالة طلب HTTP الواردة إلى كائن HttpRequestData الذي يتم تمريره إلى الدالة. يوفر هذا الكائن بيانات من الطلب، بما في ذلك HeadersURLCookiesIdentitiesرسالة و اختياريا.Body هذا الكائن هو تمثيل لطلب HTTP ولكنه غير متصل مباشرة بمستمع HTTP الأساسي أو الرسالة المستلمة.

وبالمثل، ترجع الدالة كائن HttpResponseData ، والذي يوفر البيانات المستخدمة لإنشاء استجابة HTTP، بما في ذلك رسالة StatusCodeو Headersورسالة Bodyاختياريا.

يوضح المثال التالي استخدام HttpRequestData و HttpResponseData:

[Function(nameof(HttpFunction))]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequestData req,
    FunctionContext executionContext)
{
    var logger = executionContext.GetLogger(nameof(HttpFunction));
    logger.LogInformation("message logged");

    var response = req.CreateResponse(HttpStatusCode.OK);
    response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
    response.WriteString("Welcome to .NET isolated worker !!");

    return response;
}

تسجيل الدخول

يمكنك الكتابة إلى السجلات باستخدام مثيل ILogger<T> أو ILogger . يمكن الحصول على المسجل من خلال إدخال التبعية ل ILogger<T> أو من ILoggerFactory:

public class MyFunction {
    
    private readonly ILogger<MyFunction> _logger;
    
    public MyFunction(ILogger<MyFunction> logger) {
        _logger = logger;
    }
    
    [Function(nameof(MyFunction))]
    public void Run([BlobTrigger("samples-workitems/{name}", Connection = "")] string myBlob, string name)
    {
        _logger.LogInformation($"C# Blob trigger function Processed blob\n Name: {name} \n Data: {myBlob}");
    }

}

يمكن أيضا الحصول على المسجل من كائن FunctionContext الذي تم تمريره إلى الدالة الخاصة بك. استدعاء الأسلوب GetLogger<T> أو GetLogger، لتمرير قيمة سلسلة هي اسم الفئة التي تتم كتابة السجلات فيها. عادةً ما تكون الفئة هي اسم الدالة المحددة التي تُكتب منها السجلات. لمعرفة المزيد حول الفئات، راجع مقالة المراقبة.

استخدم أساليب لكتابة ILogger<T> ILogger مستويات سجل مختلفة، مثل LogWarning أو LogError. لمعرفة المزيد حول مستويات السجل، راجع مقالة المراقبة. يمكنك تخصيص مستويات السجل للمكونات المضافة إلى التعليمات البرمجية الخاصة بك عن طريق تسجيل عوامل التصفية:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(services =>
    {
        // Registers IHttpClientFactory.
        // By default this sends a lot of Information-level logs.
        services.AddHttpClient();
    })
    .ConfigureLogging(logging =>
    {
        // Disable IHttpClientFactory Informational logs.
        // Note -- you can also remove the handler that does the logging: https://github.com/aspnet/HttpClientFactory/issues/196#issuecomment-432755765 
        logging.AddFilter("System.Net.Http.HttpClient", LogLevel.Warning);
    })
    .Build();

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

عند استخدام HostBuilder، بشكل افتراضي، يمكن أن تنتهي الاستثناءات التي تم طرحها بواسطة التعليمات البرمجية الخاصة بك في RpcExceptionملف . لإزالة هذه الطبقة الإضافية، قم بتعيين الخاصية EnableUserCodeException إلى "true" كجزء من تكوين المنشئ:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults(builder => {}, options =>
    {
        options.EnableUserCodeException = true;
    })
    .Build();

host.Run();

Application Insights

يمكنك تكوين تطبيق العملية المعزول لإرسال السجلات مباشرة إلى Application Insights. يحل هذا السلوك محل السلوك الافتراضي لترحيل السجلات من خلال المضيف. ما لم تكن تستخدم .NET Aspire، يوصى بتكوين تكامل Application Insights المباشر لأنه يمنحك التحكم في كيفية إصدار هذه السجلات.

لا يتم تمكين تكامل Application Insights بشكل افتراضي في جميع تجارب الإعداد. ستقوم بعض القوالب بإنشاء مشاريع Functions مع الحزم الضرورية وتعليق رمز بدء التشغيل. إذا كنت ترغب في استخدام تكامل Application Insights، يمكنك إلغاء التعليق على هذه الأسطر في Program.cs وملف المشروع .csproj . تصف الإرشادات الموجودة في بقية هذا القسم أيضا كيفية تمكين التكامل.

إذا كان مشروعك جزءا من تنسيق .NET Aspire، فإنه يستخدم OpenTelemetry للمراقبة بدلا من ذلك. يجب عدم تمكين تكامل Application Insights المباشر داخل مشاريع .NET Aspire. بدلا من ذلك، قم بتكوين مصدر Azure Monitor OpenTelemetry كجزء من مشروع الإعدادات الافتراضية للخدمة. إذا كان مشروع Functions الخاص بك يستخدم تكامل Application Insights في سياق .NET Aspire، فسيخطأ التطبيق عند بدء التشغيل.

تثبيت الحزم

لكتابة سجلات مباشرة إلى Application Insights من التعليمات البرمجية الخاصة بك، أضف مراجع إلى هذه الحزم في مشروعك:

يمكنك تشغيل الأوامر التالية لإضافة هذه المراجع إلى مشروعك:

dotnet add package Microsoft.ApplicationInsights.WorkerService
dotnet add package Microsoft.Azure.Functions.Worker.ApplicationInsights

تكوين بدء التشغيل

مع تثبيت الحزم، يجب عليك استدعاء AddApplicationInsightsTelemetryWorkerService() وأثناء ConfigureFunctionsApplicationInsights() تكوين الخدمة في الملف الخاص بك Program.cs ، كما في هذا المثال:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
    
var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(services => {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
    })
    .Build();

host.Run();

يضيف الاستدعاء إلى ConfigureFunctionsApplicationInsights() ، الذي يستمع إلى Functions المعرفة ActivitySource.ITelemetryModule يؤدي هذا إلى إنشاء القياس عن بعد للتبعية المطلوب لدعم التتبع الموزع. لمعرفة المزيد حول AddApplicationInsightsTelemetryWorkerService() وكيفية استخدامه، راجع Application Insights لتطبيقات خدمة العامل.

إدارة مستويات السجل

هام

يحتوي مضيف الوظائف وعامل العملية المعزول على تكوين منفصل لمستويات السجل، وما إلى ذلك. لن يؤثر أي تكوين Application Insights في host.json على التسجيل من العامل، وبالمثل، لن يؤثر التكوين الذي تم إجراؤه في التعليمات البرمجية للعامل على التسجيل من المضيف. تحتاج إلى تطبيق التغييرات في كلا المكانين إذا كان السيناريو الخاص بك يتطلب تخصيصا في كلتا الطبقتين.

يستمر باقي تطبيقك في العمل مع ILogger و ILogger<T>. ومع ذلك، بشكل افتراضي، يضيف Application Insights SDK عامل تصفية تسجيل يوجه المسجل لالتقاط التحذيرات والسجلات الأكثر خطورة فقط. إذا كنت تريد تعطيل هذا السلوك، فقم بإزالة قاعدة عامل التصفية كجزء من تكوين الخدمة:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(services => {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
    })
    .ConfigureLogging(logging =>
    {
        logging.Services.Configure<LoggerFilterOptions>(options =>
        {
            LoggerFilterRule defaultRule = options.Rules.FirstOrDefault(rule => rule.ProviderName
                == "Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider");
            if (defaultRule is not null)
            {
                options.Rules.Remove(defaultRule);
            }
        });
    })
    .Build();

host.Run();

تحسينات الأداء

يوضح هذا القسم الخيارات التي يمكنك تمكينها لتحسين الأداء حول البدء البارد.

بشكل عام، يجب أن يستخدم تطبيقك أحدث إصدارات تبعياته الأساسية. كحد أدنى، يجب تحديث مشروعك على النحو التالي:

  1. قم بترقية Microsoft.Azure.Functions.Worker إلى الإصدار 1.19.0 أو أحدث.
  2. قم بترقية Microsoft.Azure.Functions.Worker.Sdk إلى الإصدار 1.16.4 أو أحدث.
  3. أضف مرجع إطار عمل إلى Microsoft.AspNetCore.App، ما لم يستهدف تطبيقك .NET Framework.

تعرض القصاصة البرمجية التالية هذا التكوين في سياق ملف مشروع:

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.21.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.16.4" />
  </ItemGroup>

الكائنات النائبة

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

  1. قم بتحديث تكوين المشروع لاستخدام أحدث إصدارات التبعية، كما هو مفصل في القسم السابق.

  2. WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED قم بتعيين إعداد التطبيق إلى 1، والذي يمكنك القيام به باستخدام الأمر az functionapp config appsettings set:

    az functionapp config appsettings set -g <groupName> -n <appName> --settings 'WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED=1'
    

    في هذا المثال، استبدل <groupName> باسم مجموعة الموارد، واستبدل <appName> باسم تطبيق الوظائف.

  3. تأكد من netFrameworkVersion تطابق خاصية تطبيق الوظائف مع إطار العمل المستهدف لمشروعك، والذي يجب أن يكون .NET 6 أو أحدث. يمكنك القيام بذلك باستخدام الأمر az functionapp config set:

    az functionapp config set -g <groupName> -n <appName> --net-framework-version <framework>
    

    في هذا المثال، استبدل <framework> أيضا بسلسلة الإصدار المناسبة، مثل v8.0، وفقا لإصدار .NET الهدف.

  4. تأكد من تكوين تطبيق الوظائف لاستخدام عملية 64 بت، والتي يمكنك القيام بها باستخدام الأمر az functionapp config set هذا:

    az functionapp config set -g <groupName> -n <appName> --use-32bit-worker-process false
    

هام

عند تعيين WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED إلى 1، يجب تعيين جميع تكوينات تطبيق الوظائف الأخرى بشكل صحيح. وإلا، فقد يفشل بدء تشغيل تطبيق الوظائف.

المنفذ المحسن

منفذ الدالة هو مكون من النظام الأساسي الذي يتسبب في تشغيل الاستدعاءات. يتم تمكين إصدار محسن من هذا المكون بشكل افتراضي بدءا من الإصدار 1.16.2 من SDK. ولا يلزم وجود تكوين آخر إضافي.

ReadyToRun

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

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

نظام تشغيل التطبيق هو 32 بت1 معرف وقت التشغيل
Windows صواب win-x86
Windows خطأ win-x64
Linux صواب N/A (غير مدعوم)
Linux خطأ linux-x64

1 تطبيقات 64 بت فقط مؤهلة لبعض تحسينات الأداء الأخرى.

للتحقق مما إذا كان تطبيق Windows الخاص بك هو 32 بت أو 64 بت، يمكنك تشغيل أمر CLI التالي، واستبدال <group_name> باسم مجموعة الموارد الخاصة بك واسم <app_name> التطبيق الخاص بك. يشير إخراج "true" إلى أن التطبيق هو 32 بت، و"false" يشير إلى 64 بت.

 az functionapp config show -g <group_name> -n <app_name> --query "use32BitWorkerProcess"

يمكنك تغيير التطبيق الخاص بك إلى 64 بت باستخدام الأمر التالي، باستخدام نفس الاستبدالات:

az functionapp config set -g <group_name> -n <app_name> --use-32bit-worker-process false`

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

<PropertyGroup>
  <TargetFramework>net8.0</TargetFramework>
  <AzureFunctionsVersion>v4</AzureFunctionsVersion>
  <RuntimeIdentifier>win-x64</RuntimeIdentifier>
  <PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>

إذا كنت لا تريد تعيين <RuntimeIdentifier> كجزء من ملف المشروع، يمكنك أيضا تكوين هذا كجزء من إيماءة النشر نفسها. على سبيل المثال، باستخدام تطبيق وظائف Windows 64 بت، سيكون الأمر .NET CLI:

dotnet publish --runtime win-x64

في Visual Studio، يجب تعيين خيار وقت التشغيل الهدف في ملف تعريف النشر إلى معرف وقت التشغيل الصحيح. عند التعيين إلى القيمة الافتراضية ل Portable، لا يتم استخدام ReadyToRun.

النشر إلى Azure Functions

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

يمكنك أيضا نشر تطبيق الوظائف في حاوية Linux. لمزيد من المعلومات، راجع العمل مع الحاويات وAzure Functions.

إنشاء موارد Azure

يمكنك إنشاء تطبيق الوظائف والموارد المطلوبة الأخرى في Azure باستخدام إحدى هذه الطرق:

  • Visual Studio: يمكن ل Visual Studio إنشاء موارد لك أثناء عملية نشر التعليمات البرمجية.
  • Visual Studio Code: يمكن ل Visual Studio Code الاتصال باشتراكك، وإنشاء الموارد التي يحتاجها تطبيقك، ثم نشر التعليمات البرمجية الخاصة بك.
  • Azure CLI: يمكنك استخدام Azure CLI لإنشاء الموارد المطلوبة في Azure.
  • Azure PowerShell: يمكنك استخدام Azure PowerShell لإنشاء الموارد المطلوبة في Azure.
  • قوالب التوزيع: يمكنك استخدام قوالب ARM وملفات Bicep لأتمتة نشر الموارد المطلوبة إلى Azure. تأكد من أن القالب يتضمن أي إعدادات مطلوبة.
  • مدخل Microsoft Azure: يمكنك إنشاء الموارد المطلوبة في مدخل Microsoft Azure.

نشر التطبيق الخاص بك

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

  • Visual Studio: نشر يدوي بسيط أثناء التطوير.
  • Visual Studio Code: نشر يدوي بسيط أثناء التطوير.
  • Azure Functions Core Tools: نشر ملف المشروع من سطر الأوامر.
  • التوزيع المستمر: مفيد للصيانة المستمرة، بشكل متكرر إلى فتحة التقسيم المرحلي.
  • قوالب التوزيع: يمكنك استخدام قوالب ARM أو ملفات Bicep لأتمتة عمليات نشر الحزمة.

للحصول على مزيدٍ من المعلومات، راجع تقنيات النشر في Azure Functions.

حمولة النشر

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

يجب أن تتطابق حمولة النشر مع إخراج أمر، على الرغم من dotnet publish ذلك دون تضمين المجلد الأصل. يجب إنشاء أرشيف zip من الملفات التالية:

  • .azurefunctions/
  • extensions.json
  • functions.metadata
  • host.json
  • worker.config.json
  • مشروعك القابل للتنفيذ (تطبيق وحدة تحكم)
  • الملفات والدلائل الداعمة الأخرى النظير إلى ذلك القابل للتنفيذ

يتم إنشاء هذه الملفات بواسطة عملية الإنشاء، ولا يقصد تحريرها مباشرة.

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

متطلبات التوزيع

هناك بعض المتطلبات لتشغيل وظائف .NET في نموذج العامل المعزول في Azure، اعتمادا على نظام التشغيل:

عند إنشاء تطبيق الوظائف في Azure باستخدام الأساليب الموجودة في القسم السابق، تتم إضافة هذه الإعدادات المطلوبة لك. عند إنشاء هذه الموارد باستخدام قوالب ARM أو ملفات Bicep للأتمتة، يجب التأكد من تعيينها في القالب.

.NET Aspire (معاينة)

.NET Aspire هو مكدس تم استطلاع آراءه يبسط تطوير التطبيقات الموزعة في السحابة. يمكنك إدراج مشاريع نموذج العامل المعزولة .NET 8 و.NET 9 في تنسيقات Aspire 9.0 باستخدام دعم المعاينة. يوضح القسم المتطلبات الأساسية للتجنيد.

يتطلب هذا التكامل إعدادا محددا:

  • استخدم Aspire 9.0 أو أحدث و.NET 9 SDK. يدعم Aspire 9.0 أطر عمل .NET 8 و.NET 9.
  • إذا كنت تستخدم Visual Studio، فقم بتحديث الإصدار 17.12 أو أحدث. يجب أن يكون لديك أيضا أحدث إصدار من أدوات Functions ل Visual Studio. للتحقق من وجود تحديثات، انتقل إلى خيارات الأدوات>، واختر وظائف Azure ضمن المشاريع والحلول. حدد التحقق من وجود تحديثات وتثبيت التحديثات كما هو مطلوب.
  • في مشروع مضيف تطبيق Aspire:
    • يجب الرجوع إلى Aspire.Hosting.Azure.Functions.
    • يجب أن يكون لديك مرجع مشروع إلى مشروع Functions الخاص بك.
    • في مضيف Program.csالتطبيق ، يجب عليك أيضا تضمين المشروع عن طريق الاتصال AddAzureFunctionsProject<TProject>() على .IDistributedApplicationBuilder يتم استخدام هذا الأسلوب بدلا من الذي تستخدمه AddProject<TProject>() مع أنواع المشاريع الأخرى. إذا كنت تستخدم AddProject<TProject>()فقط ، فلن يبدأ مشروع Functions بشكل صحيح.
  • في مشروع Functions:
    • يجب الرجوع إلى إصدارات 2.x من Microsoft.Azure.Functions.Worker وMicrosoft.Azure.Functions.Worker.Sdk. يجب عليك أيضا تحديث أي مراجع لديك إلى Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore الإصدار 2.x أيضا.
    • Program.cs يجب أن تستخدم IHostApplicationBuilder إصدار بدء تشغيل مثيل المضيف.
    • إذا كنت ترغب في استخدام الإعدادات الافتراضية لخدمة Aspire، يجب تضمين مرجع مشروع إلى مشروع الإعدادات الافتراضية للخدمة. قبل إنشاء الخاص بك IHostApplicationBuilder في Program.cs، يجب عليك أيضا تضمين استدعاء إلى builder.AddServiceDefaults().
    • يجب عدم الاحتفاظ بالتكوين في local.settings.json، وبصرف النظر عن FUNCTIONS_WORKER_RUNTIME الإعداد، والذي يجب أن يظل "dotnet-isolated". يجب تعيين تكوين آخر من خلال مشروع مضيف التطبيق.
    • يجب إزالة أي تكاملات مباشرة ل Application Insights. تتم معالجة المراقبة في Aspire بدلا من ذلك من خلال دعم OpenTelemetry الخاص بها.

يوضح المثال التالي الحد الأدنى Program.cs لمشروع App Host:

var builder = DistributedApplication.CreateBuilder(args);

builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject");

builder.Build().Run();

يوضح المثال التالي الحد الأدنى Program.cs لمشروع Functions المستخدم في Aspire:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var builder = FunctionsApplication.CreateBuilder(args);

builder.AddServiceDefaults();

builder.ConfigureFunctionsWebApplication();

builder.Build().Run();

لا يتضمن هذا تكوين Application Insights الافتراضي الذي تراه في العديد من الأمثلة الأخرى Program.cs في هذه المقالة. بدلا من ذلك، يتم تكوين تكامل OpenTelemetry الخاص ب Aspire من خلال builder.AddServiceDefaults() الاستدعاء.

اعتبارات وأفضل الممارسات لتكامل .NET Aspire

ضع في اعتبارك النقاط التالية عند تقييم .NET Aspire مع Azure Functions:

  • دعم Azure Functions مع .NET Aspire قيد المعاينة حاليا. أثناء فترة المعاينة، عند نشر حل Aspire إلى Azure، يتم نشر مشاريع الوظائف كموارد Azure Container Apps دون تغيير الحجم المستند إلى الحدث. لا يتوفر دعم Azure Functions للتطبيقات المنشورة في هذا الوضع.
  • يقتصر تكوين المشغل والربط من خلال Aspire حاليا على عمليات تكامل محددة. راجع تكوين الاتصال مع Aspire للحصول على التفاصيل.
  • Program.cs يجب أن تستخدم IHostApplicationBuilder إصدار بدء تشغيل مثيل المضيف. يسمح لك هذا باستدعاء builder.AddServiceDefaults() لإضافة الإعدادات الافتراضية لخدمة .NET Aspire إلى مشروع Functions الخاص بك.
  • يستخدم Aspire OpenTelemetry للمراقبة. يمكنك تكوين تطمح لتصدير بيانات تتبع الاستخدام إلى Azure Monitor من خلال مشروع الإعدادات الافتراضية للخدمة. في العديد من سياقات Azure Functions الأخرى، قد تقوم بتضمين التكامل المباشر مع Application Insights عن طريق تسجيل خدمة عامل القياس عن بعد. هذا غير مستحسن في أسباير ويمكن أن يؤدي إلى أخطاء وقت التشغيل مع الإصدار 2.22.0 من Microsoft.ApplicationInsights.WorkerService. يجب إزالة أي تكاملات Application Insights مباشرة من مشروع Functions الخاص بك عند استخدام Aspire.
  • بالنسبة لمشاريع الوظائف المدرجة في تنسيق Aspire، يجب أن يأتي معظم تكوين التطبيق من مشروع مضيف تطبيق Aspire. يجب عليك عادة تجنب تعيين الأشياء في local.settings.json، بخلاف FUNCTIONS_WORKER_RUNTIME الإعداد. إذا تم تعيين نفس متغير البيئة بواسطة local.settings.json و Aspire، يستخدم النظام إصدار Aspire.
  • لا تقم بتكوين محاكي التخزين لأي اتصالات في local.settings.json. تتضمن العديد من قوالب بدء الوظائف المحاكي كافتراضي ل AzureWebJobsStorage. ومع ذلك، يمكن أن يطالب تكوين المحاكي بعض IDEs ببدء إصدار من المحاكي الذي يمكن أن يتعارض مع الإصدار الذي يستخدمه Aspire.

تكوين الاتصال مع Aspire

تتطلب Azure Functions اتصال تخزين مضيف (AzureWebJobsStorage) للعديد من سلوكياتها الأساسية. عند الاتصال AddAzureFunctionsProject<TProject>() في مشروع مضيف التطبيق الخاص بك، يتم إنشاء اتصال افتراضي AzureWebJobsStorage وتوفيره إلى مشروع Functions. يستخدم هذا الاتصال الافتراضي محاكي التخزين لتشغيل التطوير المحلي وتوفير حساب تخزين تلقائيا عند نشره. للحصول على عنصر تحكم إضافي، يمكنك استبدال هذا الاتصال باستدعاء .WithHostStorage() مورد مشروع Functions.

يوضح المثال التالي الحد الأدنى Program.cs لمشروع مضيف تطبيق يحل محل تخزين المضيف:

var builder = DistributedApplication.CreateBuilder(args);

var myHostStorage = builder.AddAzureStorage("myHostStorage");

builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
    .WithHostStorage(myHostStorage);

builder.Build().Run();

إشعار

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

تشير المشغلات والروابط إلى الاتصالات حسب الاسم. يتم تمكين بعض عمليات تكامل Aspire لتوفير هذه من خلال استدعاء WithReference() على مورد المشروع:

تكامل تطمح ملاحظات
Azure Blobs عندما يقوم Aspire بتوفير المورد، فإنه يتم تعيينه افتراضيا لإنشاء تعيينات الأدوار لأدوار Storage Blob Data Contributor، وStorage Queue Data Contributor، وStorage Table Data Contributor .
قوائم انتظار Azure عندما يقوم Aspire بتوفير المورد، فإنه يتم تعيينه افتراضيا لإنشاء تعيينات الأدوار لأدوار Storage Blob Data Contributor، وStorage Queue Data Contributor، وStorage Table Data Contributor .
مراكز أحداث Azure عندما يقوم Aspire بتوفير المورد، يتم تعيينه افتراضيا لإنشاء تعيين دور باستخدام دور مالك بيانات Azure Event Hubs.
ناقل خدمة Azure عندما يقوم Aspire بتوفير المورد، يتم تعيينه افتراضيا لإنشاء تعيين دور باستخدام دور مالك البيانات ناقل خدمة Azure.

يوضح المثال التالي الحد الأدنى Program.cs لمشروع مضيف تطبيق يقوم بتكوين مشغل قائمة انتظار. في هذا المثال، تم Connection تعيين الخاصية الخاصة بمشغل قائمة الانتظار المقابلة إلى "MyQueueTriggerConnection".

var builder = DistributedApplication.CreateBuilder(args);

var myAppStorage = builder.AddAzureStorage("myAppStorage").RunAsEmulator();
var queues = myAppStorage.AddQueues("queues");

builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
    .WithReference(queues, "MyQueueTriggerConnection");

builder.Build().Run();

بالنسبة للتكاملات الأخرى، يستدعي WithReference تعيين التكوين بطريقة مختلفة، ما يجعله متاحا لتكاملات عميل Aspire، ولكن ليس للمشغلات والروابط. بالنسبة إلى عمليات التكامل هذه، يجب عليك استدعاء WithEnvironment() لتمرير معلومات الاتصال للمشغل أو الربط لحله. يوضح المثال التالي كيفية تعيين متغير البيئة "MyBindingConnection" لمورد يعرض تعبير سلسلة الاتصال:

builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
    .WithEnvironment("MyBindingConnection", otherIntegration.Resource.ConnectionStringExpression);

يمكنك تكوين كل من WithReference() وإذا WithEnvironment() كنت تريد استخدام اتصال بواسطة تكاملات عميل Aspire ونظام المشغلات والروابط.

بالنسبة لبعض الموارد، قد تختلف بنية الاتصال بين وقت تشغيله محليا وعند نشره إلى Azure. في المثال السابق، otherIntegration يمكن أن يكون موردا يعمل كمحاكي، لذلك ConnectionStringExpression سيعيد المحاكي سلسلة الاتصال. ومع ذلك، عند نشر المورد، قد يقوم "أسباير" بإعداد اتصال يستند إلى الهوية، وسيعيد ConnectionStringExpression URI الخاص بالخدمة. في هذه الحالة، لإعداد الاتصالات المستندة إلى الهوية ل Azure Functions، قد تحتاج إلى توفير اسم متغير بيئة مختلف. يستخدم builder.ExecutionContext.IsPublishMode المثال التالي لإضافة اللاحقة الضرورية بشكل مشروط:

builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
    .WithEnvironment("MyBindingConnection" + (builder.ExecutionContext.IsPublishMode ? "__serviceUri" : ""), otherIntegration.Resource.ConnectionStringExpression);

اعتمادا على السيناريو الخاص بك، قد تحتاج أيضا إلى ضبط الأذونات التي سيتم تعيينها للاتصال المستند إلى الهوية. يمكنك استخدام ConfigureConstruct<T>() الأسلوب لتخصيص كيفية تكوين Aspire للبنية الأساسية عند نشر مشروعك.

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

التصحيح

عند التشغيل محليا باستخدام Visual Studio أو Visual Studio Code، يمكنك تصحيح أخطاء مشروع العامل المعزول .NET كالمعتاد. ومع ذلك، هناك سيناريوهان لتصحيح الأخطاء لا يعملان كما هو متوقع.

التصحيح عن بُعد باستخدام Visual Studio

نظرا لأن تطبيق معالجة العامل المعزول يعمل خارج وقت تشغيل الوظائف، تحتاج إلى إرفاق مصحح الأخطاء البعيد بعملية منفصلة. لمعرفة المزيد عن التصحيح باستخدام Visual Studio، راجع التصحيح عن بُعد.

تصحيح الأخطاء عند استهداف .NET Framework

إذا كان مشروعك المعزول يستهدف .NET Framework 4.8، فستحتاج إلى اتخاذ خطوات يدوية لتمكين تصحيح الأخطاء. هذه الخطوات غير مطلوبة إذا كنت تستخدم إطار عمل هدف آخر.

يجب أن يبدأ تطبيقك باستدعاء FunctionsDebugger.Enable(); كأول عملية له. يحدث هذا في أسلوب Main() قبل تهيئة HostBuilder. Program.cs يجب أن يبدو الملف مشابها لهذا:

using System;
using System.Diagnostics;
using Microsoft.Extensions.Hosting;
using Microsoft.Azure.Functions.Worker;
using NetFxWorker;

namespace MyDotnetFrameworkProject
{
    internal class Program
    {
        static void Main(string[] args)
        {
            FunctionsDebugger.Enable();

            var host = new HostBuilder()
                .ConfigureFunctionsWorkerDefaults()
                .Build();

            host.Run();
        }
    }
}

بعد ذلك، تحتاج إلى إرفاق العملية يدويًا باستخدام مصحح أخطاء .NET Framework. لا يقوم Visual Studio بذلك تلقائيا لتطبيقات .NET Framework لعملية العامل المعزولة حتى الآن، ويجب تجنب عملية "بدء تصحيح الأخطاء".

في دليل المشروع (أو دليل إخراج الإنشاء الخاص به )، قم بتشغيل:

func host start --dotnet-isolated-debug

يؤدي هذا إلى بدء تشغيل العامل الخاص بك، وتتوقف العملية مع الرسالة التالية:

Azure Functions .NET Worker (PID: <process id>) initialized in debug mode. Waiting for debugger to attach...

حيث <process id> هو المعرّف لعملية العامل الخاص بك. يمكنك الآن استخدام Visual Studio لإرفاق العملية يدويًا. للحصول على إرشادات حول هذه العملية، راجع كيفية الإرفاق بعملية تشغيل.

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

معاينة إصدارات .NET

قبل إصدار متوفر بشكل عام، قد يتم إصدار .NET في حالة معاينة أو Go-live . راجع نهج الدعم الرسمي ل .NET للحصول على تفاصيل حول هذه الحالات.

في حين أنه قد يكون من الممكن استهداف إصدار معين من مشروع وظائف محلي، قد لا تتوفر تطبيقات الوظائف المستضافة في Azure هذا الإصدار. يمكن استخدام Azure Functions فقط مع إصدارات المعاينة أو Go-live المذكورة في هذا القسم.

لا تعمل Azure Functions حاليا مع أي إصدارات من .NET "Preview" أو "Go-live". راجع الإصدارات المدعومة للحصول على قائمة بالإصدارات المتوفرة بشكل عام التي يمكنك استخدامها.

استخدام معاينة .NET SDK

لاستخدام Azure Functions مع إصدار معاينة من .NET، تحتاج إلى تحديث مشروعك من خلال:

  1. تثبيت إصدار .NET SDK ذي الصلة في التطوير الخاص بك
  2. تغيير الإعداد في TargetFramework .csproj الملف

عند النشر إلى تطبيق الوظائف في Azure، تحتاج أيضا إلى التأكد من توفير إطار العمل للتطبيق. أثناء فترة المعاينة، قد لا تظهر بعض الأدوات والتجارب إصدار المعاينة الجديد كخيار. إذا كنت لا ترى إصدار المعاينة مضمنا في مدخل Microsoft Azure، على سبيل المثال، يمكنك استخدام واجهة برمجة تطبيقات REST أو قوالب Bicep أو Azure CLI لتكوين الإصدار يدويا.

بالنسبة للتطبيقات المستضافة على Windows، استخدم أمر Azure CLI التالي. استبدل <groupName> باسم مجموعة الموارد، واستبدل <appName> باسم تطبيق الوظائف. استبدل <framework> بسلسلة الإصدار المناسبة، مثل v8.0.

az functionapp config set -g <groupName> -n <appName> --net-framework-version <framework>

اعتبارات استخدام إصدارات معاينة .NET

ضع هذه الاعتبارات في الاعتبار عند استخدام Functions مع إصدارات المعاينة من .NET:

  • عند تأليف وظائفك في Visual Studio، يجب استخدام Visual Studio Preview، والذي يدعم إنشاء مشاريع Azure Functions باستخدام .NET preview SDKs.

  • تأكد من أن لديك أحدث أدوات وقوالب Functions. لتحديث الأدوات الخاصة بك:

    1. انتقل إلى خيارات الأدوات>، واختر وظائف Azure ضمن المشاريع والحلول.
    2. حدد التحقق من وجود تحديثات وتثبيت التحديثات كما هو مطلوب.
  • أثناء فترة المعاينة، قد يكون لبيئة التطوير إصدار أحدث من معاينة .NET من الخدمة المستضافة. قد يؤدي ذلك إلى فشل تطبيق الوظائف عند نشره. لمعالجة ذلك، يمكنك تحديد إصدار SDK لاستخدامه في global.json.

    1. dotnet --list-sdks قم بتشغيل الأمر ولاحظ إصدار المعاينة الذي تستخدمه حاليا أثناء التطوير المحلي.
    2. dotnet new globaljson --sdk-version <SDK_VERSION> --force قم بتشغيل الأمر ، حيث <SDK_VERSION> هو الإصدار الذي تستخدمه محليا. على سبيل المثال، dotnet new globaljson --sdk-version dotnet-sdk-8.0.100-preview.7.23376.3 --force يتسبب النظام في استخدام .NET 8 Preview 7 SDK عند إنشاء مشروعك.

إشعار

نظرا لتحميل أطر عمل المعاينة في الوقت المناسب، يمكن أن تواجه تطبيقات الوظائف التي تعمل على Windows أوقات بدء باردة متزايدة مقارنة بإصدارات GA السابقة.

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