Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Orchestrator-funktioner kan anropa andra orkestreringsfunktioner som underorkestreringar. En underordnad orkestrering körs som en del av den anropande (överordnade) orkestratorn och fungerar ur anroparens perspektiv som en aktivitet: den kan returnera ett värde, utlösa undantag som fångas av den överordnade och stödja automatiskt återförsök.
När du ska använda underorkestreringar
Använd underorkestreringar när du behöver:
- Skapa återanvändbara byggblock för arbetsflöden: Extrahera ett arbetsflöde i flera steg till en egen orkestrerare så att flera överordnade orkestreringar kan anropa det.
- Distribuera orkestreringar parallellt: Schemalägg många instanser av samma orkestrator samtidigt och vänta tills alla har slutförts.
- Organisera komplexa arbetsflöden: Dela upp en stor orkestrering i namngivna, testbara bitar i stället för en enda lång funktion.
Anmärkning
Underorkestreringar måste definieras i samma app som den överordnade orkestreringen. Om du vill anropa orkestreringar i en annan app använder du HTTP 202-avsökningsmönstret i stället. Mer information finns i HTTP-funktioner.
I den här artikeln:
- Definiera en suborkestrering — exempel på konfiguration för en enskild enhet
- Kör underorkestreringar parallellt – Fan-out-mönster med deterministiska instans-ID:n
Anmärkning
I PowerShell stöds underorkestreringar endast i fristående SDK: AzureFunctions.PowerShell.Durable.SDK. Skillnaderna mellan fristående SDK och den äldre inbyggda SDK:t finns i migreringsguiden.
Definiera en underorkestrering
I följande exempel visas ett IoT-scenario där flera enheter måste konfigureras. Funktionen representerar det installationsarbetsflöde som körs för varje enhet:
Isolerad arbetsmodell
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: ...
}
Processmodell
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;
}
}
Den här orkestreringsfunktionen kan köras fristående för enstaka enhetskonfiguration, eller så kan en överordnad orkestrerare schemalägga den som en underorkestrering med api:et call-sub-orchestrator .
Köra underorkestreringar parallellt
I följande exempel visas en överordnad orkestrerare som fläktar ut flera underorkestreringar parallellt. Vissa språk använder ett deterministiskt underordnat instans-ID (härlett från det överordnade instans-ID:t plus ett index) för att förhindra duplicerade underorkestreringar under återspelning.
Isolerad arbetsmodell
[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);
// ...
}
Processmodell
[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);
// ...
}
Nästa steg
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;
}
}