Szybki start: tworzenie aplikacji Durable Functions w języku C#

Użyj funkcji Durable Functions, będącej częścią Azure Functions, aby tworzyć bezserwerowe przepływy pracy z zachowaniem stanu w języku C#. W tym przewodniku Szybki start sklonujesz i uruchomisz przykładową aplikację, która pokazuje wzorzec orkiestracji z łańcuchem funkcji:

  • Łańcuch funkcji: sekwencyjnie wywołuje działania (Tokio → Seattle → Londynie).

Na końcu uruchomisz orkiestrację lokalnie z emulatorem Durable Task Scheduler i będzie można wyświetlić jej stan w pulpicie nawigacyjnym.

  • Sklonuj i przygotuj przykładowy projekt Hello Cities.
  • Skonfiguruj emulator narzędzia Durable Task Scheduler i Azurite na potrzeby programowania lokalnego.
  • Skompiluj i uruchom aplikację funkcji oraz uruchom orkiestrację.
  • Przejrzyj stan orkiestracji i dane wyjściowe na pulpicie nawigacyjnym narzędzia Durable Task Scheduler.

Wymagania wstępne

Konfigurowanie emulatora harmonogramu zadań Durable Task Scheduler

Emulator harmonogramu zadań Durable udostępnia lokalne środowisko programistyczne, dzięki czemu można testować aranżacje bez subskrypcji Azure. Host funkcji platformy .NET wymaga również Azurite do lokalnego magazynu danych.

Uruchom oba kontenery:

docker run -d --name dtsemulator -p 8080:8080 -p 8082:8082 \
  mcr.microsoft.com/dts/dts-emulator:latest

docker run -d --name azurite -p 10000:10000 -p 10001:10001 -p 10002:10002 \
  mcr.microsoft.com/azure-storage/azurite

Wskazówka

Po uruchomieniu emulatora możesz uzyskać dostęp do pulpitu nawigacyjnego narzędzia Durable Task Scheduler pod adresem , http://localhost:8082 aby monitorować aranżacje.

Uruchom przykład szybkiego startu

  1. Przejdź do przykładowego katalogu Hello Cities:

    cd samples/durable-functions/dotnet/HelloCities/http
    
  2. local.settings.json Utwórz plik z konfiguracją emulatora:

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
        "DURABLE_TASK_SERVICE_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
        "TASKHUB_NAME": "default"
      }
    }
    
  3. Skompiluj projekt:

    dotnet build
    
  4. Uruchom aplikację funkcji:

    func start
    
  5. W osobnym terminalu wyzwól orkiestrację:

    $response = Invoke-RestMethod -Method POST -Uri http://localhost:7071/api/DurableFunctionsOrchestrationCSharp1_HttpStart
    $response
    

    Odpowiedź zawiera adresy URL stanu wystąpienia orkiestracji. statusQueryGetUri Skopiuj wartość i uruchom ją, aby sprawdzić wynik:

    Invoke-RestMethod -Uri $response.statusQueryGetUri
    

Oczekiwane dane wyjściowe

Żądanie POST zwraca odpowiedź w formacie JSON z adresami URL statusu. Przykład:

{
  "id": "<instanceId>",
  "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/<instanceId>?code=...",
  "sendEventPostUri": "...",
  "terminatePostUri": "...",
  "purgeHistoryDeleteUri": "..."
}

Gdy wysyłasz zapytanie do statusQueryGetUri i wartość runtimeStatus orkiestracji to Completed, wyniki powitania znajdziesz w polu output:

{
  "name": "DurableFunctionsOrchestrationCSharp1",
  "runtimeStatus": "Completed",
  "output": ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
}

Wskazówka

Jeśli runtimeStatus pokazuje Running lub Pending, zaczekaj chwilę i ponownie wykonaj zapytanie do statusQueryGetUri.

Otwórz pulpit narzędzia Durable Task Scheduler pod adresem http://localhost:8082, aby wyświetlić stan orkiestracji i historię wykonywania.

Omówienie kodu

Przykładowy projekt w DurableFunctionsOrchestrationCSharp1.cs zawiera wszystkie trzy typy funkcji potrzebne dla aplikacji Durable Functions.

Funkcja aktywności

Działanie SayHello przyjmuje nazwę miasta i zwraca powitanie:

[Function(nameof(SayHello))]
public static string SayHello([ActivityTrigger] string name, FunctionContext executionContext)
{
    ILogger logger = executionContext.GetLogger("SayHello");
    logger.LogInformation("Saying hello to {name}.", name);
    return $"Hello {name}!";
}

Funkcja orkiestratora

Orkiestrator wywołuje SayHello sekwencyjnie dla trzech miast:

[Function(nameof(DurableFunctionsOrchestrationCSharp1))]
public static async Task<List<string>> RunOrchestrator(
    [OrchestrationTrigger] TaskOrchestrationContext context)
{
    ILogger logger = context.CreateReplaySafeLogger(nameof(DurableFunctionsOrchestrationCSharp1));
    logger.LogInformation("Saying hello.");
    var outputs = new List<string>();

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

    return outputs;
}

Funkcja klienta

Funkcja klienta wyzwalana przez protokół HTTP uruchamia orkiestrację:

[Function("DurableFunctionsOrchestrationCSharp1_HttpStart")]
public static async Task<HttpResponseData> HttpStart(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,
    [DurableClient] DurableTaskClient client,
    FunctionContext executionContext)
{
    ILogger logger = executionContext.GetLogger("DurableFunctionsOrchestrationCSharp1_HttpStart");
    string instanceId = await client.ScheduleNewOrchestrationInstanceAsync(
        nameof(DurableFunctionsOrchestrationCSharp1));

    logger.LogInformation("Started orchestration with ID = '{instanceId}'.", instanceId);
    return await client.CreateCheckStatusResponseAsync(req, instanceId);
}

Konfiguracja

W przykładzie jako zaplecze magazynu danych użyto emulatora Durable Task Scheduler. Jest to skonfigurowane w programie host.json:

{
  "version": "2.0",
  "extensions": {
    "durableTask": {
      "storageProvider": {
        "type": "azureManaged",
        "connectionStringName": "DURABLE_TASK_SERVICE_CONNECTION_STRING"
      },
      "hubName": "%TASKHUB_NAME%"
    }
  }
}

Parametry połączenia emulatora i nazwa centrum zadań są ustawione w local.settings.json:

{
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
    "DURABLE_TASK_SERVICE_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
    "TASKHUB_NAME": "default"
  }
}

Uprzątnij zasoby

Zatrzymaj kontenery emulatora, gdy skończysz:

docker stop dtsemulator azurite && docker rm dtsemulator azurite

Następne kroki