التنسيقات الفرعية

يمكن أن تسمي دوال الأوركستراتور وظائف أوركستراتور أخرى كأوركستراشات فرعية. يعمل التوزيع الفرعي كفرع من منسق المكالمات (الوالد) ويتصرف كنشاط من منظور المتصل: يمكنه إعادة قيمة، وتنفيذ استثناءات يلتقطها الوالد، ودعم إعادة المحاولة التلقائية.

متى تستخدم التوزيعات الفرعية

استخدم التوزيعات الفرعية عندما تحتاج:

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

ملحوظة

يجب تعريف التوزيع الفرعي في نفس التطبيق الذي يعرف فيه التوزيع الأصلي. لاستدعاء التنسيقات في تطبيق مختلف، استخدم نمط استطلاع HTTP 202 بدلا من ذلك. لمزيد من المعلومات، راجع ميزات HTTP.

في هذه المقالة:

مهم

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

ملحوظة

في PowerShell، يتم دعم التنسيقات الفرعية فقط في مجموعة تطوير البرمجيات المستقلة: AzureFunctions.PowerShell.Durable.SDK. للفروقات بين SDK المستقل وSDK المدمج القديم، راجع دليل الترحيل.

تعريف توزيع فرعي

يوضح المثال التالي سيناريو إنترنت الأشياء حيث يجب إعداد عدة أجهزة. تمثل الدالة سير عمل الإعداد الذي يعمل لكل جهاز:

نموذج العامل المعزول
public static async Task DeviceProvisioningOrchestration(
    [OrchestrationTrigger] TaskOrchestrationContext context, string deviceId)
{
    // Step 1: Create an installation package in blob storage and return a SAS URL.
    Uri sasUrl = await context.CallActivityAsync<Uri>("CreateInstallationPackage", deviceId);

    // Step 2: Notify the device that the installation package is ready.
    await context.CallActivityAsync("SendPackageUrlToDevice", (deviceId, sasUrl));

    // Step 3: Wait for the device to acknowledge that it has downloaded the new package.
    await context.WaitForExternalEvent<bool>("DownloadCompletedAck");

    // Step 4: ...
}

النموذج أثناء العملية
public static async Task DeviceProvisioningOrchestration(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    string deviceId = context.GetInput<string>();

    // Step 1: Create an installation package in blob storage and return a SAS URL.
    Uri sasUrl = await context.CallActivityAsync<Uri>("CreateInstallationPackage", deviceId);

    // Step 2: Notify the device that the installation package is ready.
    await context.CallActivityAsync("SendPackageUrlToDevice", Tuple.Create(deviceId, sasUrl));

    // Step 3: Wait for the device to acknowledge that it has downloaded the new package.
    await context.WaitForExternalEvent<bool>("DownloadCompletedAck");

    // Step 4: ...
}
using Microsoft.DurableTask;

[DurableTask]
public class DeviceProvisioningOrchestration : TaskOrchestrator<string, object?>
{
    public override async Task<object?> RunAsync(TaskOrchestrationContext context, string deviceId)
    {
        // Step 1: Create an installation package in blob storage and return a SAS URL.
        Uri sasUrl = await context.CallActivityAsync<Uri>("CreateInstallationPackage", deviceId);

        // Step 2: Notify the device that the installation package is ready.
        await context.CallActivityAsync("SendPackageUrlToDevice", (deviceId, sasUrl.ToString()));

        // Step 3: Wait for the device to acknowledge that it has downloaded the new package.
        await context.WaitForExternalEvent<bool>("DownloadCompletedAck");

        // Step 4: ...
        return null;
    }
}

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

تشغيل التوزيعات الفرعية بالتوازي

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

نموذج العامل المعزول
[Function("ProvisionNewDevices")]
public static async Task ProvisionNewDevices(
    [OrchestrationTrigger] TaskOrchestrationContext context)
{
    string[] deviceIds = await context.CallActivityAsync<string[]>("GetNewDeviceIds");

    // Run multiple device provisioning flows in parallel
    var provisioningTasks = new List<Task>();
    foreach (string deviceId in deviceIds)
    {
        Task provisionTask = context.CallSubOrchestratorAsync("DeviceProvisioningOrchestration", deviceId);
        provisioningTasks.Add(provisionTask);
    }

    await Task.WhenAll(provisioningTasks);

    // ...
}

النموذج أثناء العملية
[FunctionName("ProvisionNewDevices")]
public static async Task ProvisionNewDevices(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    string[] deviceIds = await context.CallActivityAsync<string[]>("GetNewDeviceIds");

    // Run multiple device provisioning flows in parallel
    var provisioningTasks = new List<Task>();
    foreach (string deviceId in deviceIds)
    {
        Task provisionTask = context.CallSubOrchestratorAsync("DeviceProvisioningOrchestration", deviceId);
        provisioningTasks.Add(provisionTask);
    }

    await Task.WhenAll(provisioningTasks);

    // ...
}

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

using Microsoft.DurableTask;

[DurableTask]
public class ProvisionNewDevices : TaskOrchestrator<object?, object?>
{
    public override async Task<object?> RunAsync(TaskOrchestrationContext context, object? input)
    {
        string[] deviceIds = await context.CallActivityAsync<string[]>("GetNewDeviceIds");

        // Run multiple device provisioning flows in parallel
        var provisioningTasks = new List<Task>();
        foreach (string deviceId in deviceIds)
        {
            Task provisionTask = context.CallSubOrchestratorAsync("DeviceProvisioningOrchestration", deviceId);
            provisioningTasks.Add(provisionTask);
        }

        await Task.WhenAll(provisioningTasks);
        return null;
    }
}

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