تعيين واستعلام حالة التنسيق المخصص

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

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

التحذير

الحمولة المخصصة للحالة محدودة ب 16 كيلوبايت من نص JSON UTF-16. إذا كنت بحاجة إلى حمولة أكبر، استخدم التخزين الخارجي وقم بتخزين مرجع (مثل عنوان URL blob) في الحالة المخصصة بدلا من ذلك.

مهم

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

في عام دالات Azure، تتوفر هذه الحالة عبر واجهة برمجة تطبيقات GetStatus HTTP أو المكافئة ><واجهة برمجة تطبيقات ال SDK على كائن عميل التنسيق.

في SDKs للمهام الدائمة، تتوفر هذه الحالة من خلال واجهات برمجة تطبيقات استعلام حالة التنسيق على DurableTaskClient (على سبيل المثال، GetInstanceAsync في .NET أو getInstanceMetadata في Java).

مهم

حاليا، حزمة تطوير المهام الدائمة PowerShell غير متوفرة.

أمثلة على حالات استخدام لحالة توزيع توزيع مخصص

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

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

تصور تقدم التوزيع الموسيقي

في هذا النمط، يتصل SetCustomStatus المنسق (أو ما يعادله بلغتك) بعد انتهاء كل نشاط، ويحدث الحالة باسم آخر مدينة مكتملة. يقوم العميل باستطلاع نقطة نهاية الحالة، ويقرأ القيمة الحالية، ويحدث مؤشر التقدم في واجهة المستخدم.

توضح العينة التالية مشاركة التقدم باستخدام نقطة نهاية حالة Durable Functions HTTP:

ملحوظة

هذه الأمثلة مكتوبة لإصدار Durable Functions 2.x وليست متوافقة مع Durable Functions 1.x. لمزيد من المعلومات حول الفروقات بين الإصدارات، راجع مقال Durable Functions versions.

[FunctionName("E1_HelloSequence")]
public static async Task<List<string>> Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var outputs = new List<string>();

    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "Tokyo"));
    context.SetCustomStatus("Tokyo");
    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "Seattle"));
    context.SetCustomStatus("Seattle");
    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "London"));
    context.SetCustomStatus("London");

    // returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
    return outputs;
}

[FunctionName("E1_SayHello")]
public static string SayHello([ActivityTrigger] string name)
{
    return $"Hello {name}!";
}

توضح العينة التالية مشاركة التقدم باستخدام واجهات برمجة تطبيقات عميل Durable Task SDK:

using System.Threading.Tasks;
using Microsoft.DurableTask;

public class HelloCities : TaskOrchestrator<object?, string>
{
    public override async Task<string> RunAsync(TaskOrchestrationContext context, object? input)
    {
        string result = "";

        result += await context.CallActivityAsync<string>("SayHello", "Tokyo") + ", ";
        context.SetCustomStatus("Tokyo");

        result += await context.CallActivityAsync<string>("SayHello", "London") + ", ";
        context.SetCustomStatus("London");

        result += await context.CallActivityAsync<string>("SayHello", "Seattle");
        context.SetCustomStatus("Seattle");

        return result;
    }
}

يمكن للعميل استطلاع بيانات التنسيق الوصفية والانتظار حتى يتم تعيين الحقل CustomStatus على "London":

using System.Threading.Tasks;
using Microsoft.DurableTask.Client;

string instanceId = await client.ScheduleNewOrchestrationInstanceAsync("HelloCities");

OrchestrationMetadata metadata = await client.WaitForInstanceStartAsync(instanceId, getInputsAndOutputs: true);
while (metadata.SerializedCustomStatus is null || metadata.ReadCustomStatusAs<string>() != "London")
{
    await Task.Delay(200);
    metadata = await client.GetInstanceAsync(instanceId, getInputsAndOutputs: true) ?? metadata;
}

يقوم كود العميل التالي باستطلاع حالة التنسيق وينتظر حتى CustomStatus يتم تعيينه قبل "London" أن يعيد الرد:

[FunctionName("HttpStart")]
public static async Task<HttpResponseMessage> Run(
    [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}")] HttpRequestMessage req,
    [DurableClient] IDurableOrchestrationClient starter,
    string functionName,
    ILogger log)
{
    // Function input comes from the request content.
    dynamic eventData = await req.Content.ReadAsAsync<object>();
    string instanceId = await starter.StartNewAsync(functionName, (string)eventData);

    log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

    DurableOrchestrationStatus durableOrchestrationStatus = await starter.GetStatusAsync(instanceId);
    while (durableOrchestrationStatus.CustomStatus.ToString() != "London")
    {
        await Task.Delay(200);
        durableOrchestrationStatus = await starter.GetStatusAsync(instanceId);
    }

    HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.OK)
    {
        Content = new StringContent(JsonConvert.SerializeObject(durableOrchestrationStatus))
    };

    return httpResponseMessage;
  }
}

إرجاع البيانات الوصفية الديناميكية إلى العملاء

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

[FunctionName("CityRecommender")]
public static void Run(
  [OrchestrationTrigger] IDurableOrchestrationContext context)
{
  int userChoice = context.GetInput<int>();

  switch (userChoice)
  {
    case 1:
    context.SetCustomStatus(new
    {
      recommendedCities = new[] {"Tokyo", "Seattle"},
      recommendedSeasons = new[] {"Spring", "Summer"}
     });
      break;
    case 2:
      context.SetCustomStatus(new
      {
                recommendedCities = new[] {"Seattle", "London"},
        recommendedSeasons = new[] {"Summer"}
      });
        break;
      case 3:
      context.SetCustomStatus(new
      {
                recommendedCities = new[] {"Tokyo", "London"},
        recommendedSeasons = new[] {"Spring", "Summer"}
      });
        break;
  }

  // Wait for user selection and refine the recommendation
}
using System.Threading.Tasks;
using Microsoft.DurableTask;

public class CityRecommender : TaskOrchestrator<int, object?>
{
    public override Task<object?> RunAsync(TaskOrchestrationContext context, int userChoice)
    {
        switch (userChoice)
        {
            case 1:
                context.SetCustomStatus(new
                {
                    recommendedCities = new[] { "Tokyo", "Seattle" },
                    recommendedSeasons = new[] { "Spring", "Summer" },
                });
                break;
            case 2:
                context.SetCustomStatus(new
                {
                    recommendedCities = new[] { "Seattle", "London" },
                    recommendedSeasons = new[] { "Summer" },
                });
                break;
            case 3:
                context.SetCustomStatus(new
                {
                    recommendedCities = new[] { "Tokyo", "London" },
                    recommendedSeasons = new[] { "Spring", "Summer" },
                });
                break;
        }

        // Wait for user selection and refine the recommendation
        return Task.FromResult<object?>(null);
    }
}

توفير بيانات قابلة للتنفيذ للعملاء

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

[FunctionName("ReserveTicket")]
public static async Task<bool> Run(
  [OrchestrationTrigger] IDurableOrchestrationContext context)
{
  string userId = context.GetInput<string>();

  int discount = await context.CallActivityAsync<int>("CalculateDiscount", userId);

  context.SetCustomStatus(new
  {
    discount = discount,
    discountTimeout = 60,
    bookingUrl = "https://www.myawesomebookingweb.com",
  });

  bool isBookingConfirmed = await context.WaitForExternalEvent<bool>("BookingConfirmed");

  context.SetCustomStatus(isBookingConfirmed
    ? new {message = "Thank you for confirming your booking."}
    : new {message = "The booking was not confirmed on time. Please try again."});

  return isBookingConfirmed;
}
using System.Threading.Tasks;
using Microsoft.DurableTask;

public class ReserveTicket : TaskOrchestrator<string, bool>
{
    public override async Task<bool> RunAsync(TaskOrchestrationContext context, string userId)
    {
        int discount = await context.CallActivityAsync<int>("CalculateDiscount", userId);

        context.SetCustomStatus(new
        {
            discount,
            discountTimeout = 60,
            bookingUrl = "https://www.myawesomebookingweb.com",
        });

        bool isBookingConfirmed = await context.WaitForExternalEvent<bool>("BookingConfirmed");
        context.SetCustomStatus(isBookingConfirmed
            ? new { message = "Thank you for confirming your booking." }
            : new { message = "The booking was not confirmed on time. Please try again." });

        return isBookingConfirmed;
    }
}

استعلام حالة التوزيع الموسيقي المخصص

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

بعد استدعاء المنسق SetCustomStatus، يمكن للعملاء الخارجيين الاستعلام عن القيمة من خلال واجهة برمجة تطبيقات HTTP المدمجة Durable Functions. على سبيل المثال:

GET /runtime/webhooks/durabletask/instances/instance123

يشمل الرد الحقل customStatus إلى جانب بيانات وصفية وقت التشغيل:

{
  "runtimeStatus": "Running",
  "input": null,
  "customStatus": { "nextActions": ["A", "B", "C"], "foo": 2 },
  "output": null,
  "createdTime": "2019-10-06T18:30:24Z",
  "lastUpdatedTime": "2019-10-06T19:40:30Z"
}

يمكنك أيضا الاستعلام عن حالة مخصصة برمجيا باستخدام SDK الخاص بعميل التنسيق. للحصول على مرجع كامل، انظر حالات الاستعلام.

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

using Microsoft.DurableTask.Client;

OrchestrationMetadata? metadata = await client.GetInstanceAsync(instanceId, getInputsAndOutputs: true);
string? customStatusJson = metadata?.SerializedCustomStatus;

التحذير

الحمولة المخصصة للحالة محدودة ب 16 كيلوبايت من نص JSON UTF-16.

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