Wat is Durable Functions?What are Durable Functions?

Durable Functions is een extensie van Azure Functions waarmee u stateful functies kunt schrijven in een serverloze rekenomgeving.Durable Functions is an extension of Azure Functions that lets you write stateful functions in a serverless compute environment. Met de extensie kunt u stateful werkstromen definiëren door Orchestrator-functies te schrijven en stateful entiteiten door entiteitsfuncties te schrijven met behulp van het Azure Functions-programmeermodel.The extension lets you define stateful workflows by writing orchestrator functions and stateful entities by writing entity functions using the Azure Functions programming model. Achter de schermen beheert de extensie status, controlepunten en het opnieuw opstarten, zodat u zich kunt concentreren op uw bedrijf.Behind the scenes, the extension manages state, checkpoints, and restarts for you, allowing you to focus on your business logic.

Ondersteunde talenSupported languages

Durable Functions ondersteunt momenteel de volgende talen:Durable Functions currently supports the following languages:

  • C#: zowel vooraf gecompileerde klassebibliotheken als C#-script.C#: both precompiled class libraries and C# script.
  • JavaScript: alleen ondersteund voor versie 2.x van de Azure Functions-runtime.JavaScript: supported only for version 2.x of the Azure Functions runtime. Versie 1.7.0 of hoger van de Durable Functions-extensie vereist.Requires version 1.7.0 of the Durable Functions extension, or a later version.
  • Python: vereist versie 2.3.1 of hoger van de Durable Functions-extensie.Python: requires version 2.3.1 of the Durable Functions extension, or a later version.
  • F#: vooraf gecompileerde klassebibliotheken en F#-script.F#: precompiled class libraries and F# script. F#-script wordt alleen ondersteund voor versie 1.x van de Azure Functions-runtime.F# script is only supported for version 1.x of the Azure Functions runtime.
  • PowerShell: ondersteuning voor Durable Functions is momenteel beschikbaar als openbare preview.PowerShell: support for Durable Functions is currently in public preview. Wordt alleen ondersteund voor versie 3.x van de Azure Functions-runtime en PowerShell 7.Supported only for version 3.x of the Azure Functions runtime and PowerShell 7. Versie 2.2.2 of hoger van de Durable Functions-extensie vereist.Requires version 2.2.2 of the Durable Functions extension, or a later version. Alleen de volgende patronen worden momenteel ondersteund: Functiekoppeling, uit-/inwaaieren asynchrone HTTP-API's.Only the following patterns are currently supported: Function chaining, Fan-out/fan-in, Async HTTP APIs.

Voor toegang tot de nieuwste functies en updates wordt aanbevolen om de nieuwste versies van de Durable Functions-extensie en de taalspecifieke Durable Functions-bibliotheken te gebruiken.To access the latest features and updates, it is recommended you use the latest versions of the Durable Functions extension and the language-specific Durable Functions libraries. Meer informatie over versies van Durable Functions.Learn more about Durable Functions versions.

Durable Functions heeft als doel alle Azure Functions-talen te ondersteunen.Durable Functions has a goal of supporting all Azure Functions languages. Zie Durable Functions issues list voor de laatste voortgangsstatus van de ondersteuning voor meer talen.See the Durable Functions issues list for the latest status of work to support additional languages.

Net als bij Azure Functions zijn er sjablonen om u te helpen bij het ontwikkelen van Durable Functions met behulp van Visual Studio 2019, Visual Studio Code en de Azure-portal.Like Azure Functions, there are templates to help you develop Durable Functions using Visual Studio 2019, Visual Studio Code, and the Azure portal.

ToepassingspatronenApplication patterns

De primaire use case voor Durable Functions is het vereenvoudigen van complexe stateful coördinatievereisten in serverloze toepassingen.The primary use case for Durable Functions is simplifying complex, stateful coordination requirements in serverless applications. In de volgende secties worden enkele typische toepassingspatronen beschreven die kunnen profiteren van Durable Functions:The following sections describe typical application patterns that can benefit from Durable Functions:

Patroon #1: FunctiekoppelingPattern #1: Function chaining

In het patroon voor functiekoppeling wordt een reeks functies in een specifieke volg orde uitgevoerd.In the function chaining pattern, a sequence of functions executes in a specific order. In dit patroon wordt de uitvoer van een functie toegepast op de invoer van een andere functie.In this pattern, the output of one function is applied to the input of another function.

Een diagram van het patroon voor functiekoppeling

U kun Durable Functions gebruiken om het patroon voor functiekoppeling bondig te implementeren zoals in het volgende voorbeeld.You can use Durable Functions to implement the function chaining pattern concisely as shown in the following example.

In dit voorbeeld zijn de waarden F1, F2, F3 en F4 de namen van andere functies in dezelfde functie-app.In this example, the values F1, F2, F3, and F4 are the names of other functions in the same function app. U kunt een controlestroom implementeren met behulp van normale imperatieve codeconstructies.You can implement control flow by using normal imperative coding constructs. Code wordt van boven naar beneden uitgevoerd.Code executes from the top down. De code kan bestaande taalsemantiek voor controlestromen bevatten, zoals voorwaarden en lussen.The code can involve existing language control flow semantics, like conditionals and loops. U kunt logica voor foutafhandeling toevoegen in try/catch/finally blokken.You can include error handling logic in try/catch/finally blocks.

[FunctionName("Chaining")]
public static async Task<object> Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    try
    {
        var x = await context.CallActivityAsync<object>("F1", null);
        var y = await context.CallActivityAsync<object>("F2", x);
        var z = await context.CallActivityAsync<object>("F3", y);
        return  await context.CallActivityAsync<object>("F4", z);
    }
    catch (Exception)
    {
        // Error handling or compensation goes here.
    }
}

U kunt de context-parameter gebruiken om andere functies aan te roepen op naam, parameters door te geven en functie-uitvoer te retourneren.You can use the context parameter to invoke other functions by name, pass parameters, and return function output. Telkens de code await aanroept controleert het Durable Functions-framework de voortgang van de huidige functie-instantie.Each time the code calls await, the Durable Functions framework checkpoints the progress of the current function instance. Als het proces of de virtuele machine halverwege tijdens de uitvoering recycleert, dan begint de functie-instantie opnieuw vanaf de voorgaande await-aanroep.If the process or virtual machine recycles midway through the execution, the function instance resumes from the preceding await call. Zie de volgende sectie, Patroon #2, voor meer informatie: Uitwaaieren/inwaaieren.For more information, see the next section, Pattern #2: Fan out/fan in.

Patroon #2: Uitwaaieren/inwaaierenPattern #2: Fan out/fan in

In het patroon uitwaaieren/inwaaieren voert u meerdere functies parallel uit en wacht u totdat alle functies zijn voltooid.In the fan out/fan in pattern, you execute multiple functions in parallel and then wait for all functions to finish. Vaak wordt er een aggregatie toegepast op de resultaten die worden geretourneerd door de functies.Often, some aggregation work is done on the results that are returned from the functions.

Een diagram van het patroon uitwaaieren/inwaaieren

Bij normale functies kunt u uitwaaieren door de functie meerdere berichten te laten sturen naar een wachtrij.With normal functions, you can fan out by having the function send multiple messages to a queue. Terug inwaaieren is veel lastiger.Fanning back in is much more challenging. Om in een normale functie in te waaieren schrijft u code om op te volgen wanneer de in de wachtrij geactiveerde functies aflopen en slaat u vervolgens de functie-uitvoer op.To fan in, in a normal function, you write code to track when the queue-triggered functions end, and then store function outputs.

De Durable Functions-extensie verwerkt dit patroon met relatief eenvoudige code:The Durable Functions extension handles this pattern with relatively simple code:

[FunctionName("FanOutFanIn")]
public static async Task Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var parallelTasks = new List<Task<int>>();

    // Get a list of N work items to process in parallel.
    object[] workBatch = await context.CallActivityAsync<object[]>("F1", null);
    for (int i = 0; i < workBatch.Length; i++)
    {
        Task<int> task = context.CallActivityAsync<int>("F2", workBatch[i]);
        parallelTasks.Add(task);
    }

    await Task.WhenAll(parallelTasks);

    // Aggregate all N outputs and send the result to F3.
    int sum = parallelTasks.Sum(t => t.Result);
    await context.CallActivityAsync("F3", sum);
}

Het uitwaaierwerk wordt verdeeld over meerdere instanties van de F2-functie.The fan-out work is distributed to multiple instances of the F2 function. Het werk wordt opgevolgd met een dynamische takenlijst.The work is tracked by using a dynamic list of tasks. Task.WhenAll wordt aangeroepen om te wachten tot alle aangeroepen functies voltooid zijn.Task.WhenAll is called to wait for all the called functions to finish. Vervolgens wordt de F2-functie-uitvoer samengevoegd uit de dynamische takenlijst en doorgegeven naar de F3-functie.Then, the F2 function outputs are aggregated from the dynamic task list and passed to the F3 function.

Het automatisch plaatsen van controlepunten bij de await-aanroep op Task.WhenAll zorgt ervoor dat een reeds voltooide taak niet opnieuw moet worden opgestart bij een potentiële crash of reboot halverwege.The automatic checkpointing that happens at the await call on Task.WhenAll ensures that a potential midway crash or reboot doesn't require restarting an already completed task.

Notitie

In zeldzame gevallen is het mogelijk dat er een crash optreedt in het venster nadat een activiteitsfunctie wordt voltooid maar voor de voltooiing wordt opgeslagen in de indelingsgeschiedenis.In rare circumstances, it's possible that a crash could happen in the window after an activity function completes but before its completion is saved into the orchestration history. Als dit gebeurt, dan wordt de activiteitsfunctie opnieuw uitgevoerd vanaf het begin nadat het proces hersteld wordt.If this happens, the activity function would re-run from the beginning after the process recovers.

Patroon #3: Asynchrone HTTP-API'sPattern #3: Async HTTP APIs

Het asynchrone HTTP API-patroon biedt een oplossing voor het probleem van de coördinatie van langdurige bewerkingen met externe clients.The async HTTP API pattern addresses the problem of coordinating the state of long-running operations with external clients. Een gebruikelijke manier om dit patroon te implementeren is door de langdurige actie te laten activeren door een HTTP-eindpunt.A common way to implement this pattern is by having an HTTP endpoint trigger the long-running action. Leid de client dan om naar een statuseindpunt dat de client bevraagt om te weten te komen wanneer de bewerking is voltooid.Then, redirect the client to a status endpoint that the client polls to learn when the operation is finished.

Een diagram van het HTTP API-patroon

Durable Functions biedt ingebouwde ondersteuning voor dit patroon, waardoor u minder complexe of zelfs helemaal geen code moet schrijven om te communiceren met de uitvoering van langdurige functies.Durable Functions provides built-in support for this pattern, simplifying or even removing the code you need to write to interact with long-running function executions. De voorbeelden van de quickstart Durable Functions (C# en JavaScript) laten een eenvoudige REST-opdracht zien die u kunt gebruiken om een nieuwe instantie van een orchestrator-functie te starten.For example, the Durable Functions quickstart samples (C# and JavaScript) show a simple REST command that you can use to start new orchestrator function instances. Nadat een instantie is gestart, worden de HTTP-API's van de webhook met de status van de orchestrator-functie weergegeven.After an instance starts, the extension exposes webhook HTTP APIs that query the orchestrator function status.

Het volgende voorbeeld geeft REST-opdrachten weer die een orchestrator starten en de status opvragen.The following example shows REST commands that start an orchestrator and query its status. Voor de duidelijkheid zijn bepaalde protocoldetails weggelaten uit het voorbeeld.For clarity, some protocol details are omitted from the example.

> curl -X POST https://myfunc.azurewebsites.net/api/orchestrators/DoWork -H "Content-Length: 0" -i
HTTP/1.1 202 Accepted
Content-Type: application/json
Location: https://myfunc.azurewebsites.net/runtime/webhooks/durabletask/instances/b79baf67f717453ca9e86c5da21e03ec

{"id":"b79baf67f717453ca9e86c5da21e03ec", ...}

> curl https://myfunc.azurewebsites.net/runtime/webhooks/durabletask/instances/b79baf67f717453ca9e86c5da21e03ec -i
HTTP/1.1 202 Accepted
Content-Type: application/json
Location: https://myfunc.azurewebsites.net/runtime/webhooks/durabletask/instances/b79baf67f717453ca9e86c5da21e03ec

{"runtimeStatus":"Running","lastUpdatedTime":"2019-03-16T21:20:47Z", ...}

> curl https://myfunc.azurewebsites.net/runtime/webhooks/durabletask/instances/b79baf67f717453ca9e86c5da21e03ec -i
HTTP/1.1 200 OK
Content-Length: 175
Content-Type: application/json

{"runtimeStatus":"Completed","lastUpdatedTime":"2019-03-16T21:20:57Z", ...}

Aangezien de Durable Functions-runtime de status voor u beheert, moet u geen eigen mechanisme voor het opvolgen van de status meer implementeren.Because the Durable Functions runtime manages state for you, you don't need to implement your own status-tracking mechanism.

De Durable Functions-extensie laat ingebouwde HTTP API's zien die langlopende indelingen beheren.The Durable Functions extension exposes built-in HTTP APIs that manage long-running orchestrations. U kunt dit patroon ook zelf implementeren met behulp van uw eigen functie-triggers (zoals HTTP, een wachtrij of Azure Event Hubs) en de indelingsclientbinding.You can alternatively implement this pattern yourself by using your own function triggers (such as HTTP, a queue, or Azure Event Hubs) and the orchestration client binding. Zo kunt u bijvoorbeeld een wachtrijbericht gebruiken om beëindiging te activeren.For example, you might use a queue message to trigger termination. Of u kunt een HTTP-trigger gebruiken die beschermd wordt door een Azure Active Directory-verificatiebeleid in plaats van de ingebouwde HTTP API's die een gegenereerde sleutel gebruiken voor verificatie.Or, you might use an HTTP trigger that's protected by an Azure Active Directory authentication policy instead of the built-in HTTP APIs that use a generated key for authentication.

Lees het artikel HTTP-functies voor meer informatie over hoe u asynchrone, langdurende processen via HTTP kunt weergeven met behulp van de Durable Functions-extensie.For more information, see the HTTP features article, which explains how you can expose asynchronous, long-running processes over HTTP using the Durable Functions extension.

Patroon #4: ControlerenPattern #4: Monitor

Het monitorpatroon verwijst naar een flexibel, terugkerend proces in een werkstroom.The monitor pattern refers to a flexible, recurring process in a workflow. Een voorbeeld daarvan is navragen tot er aan specifieke voorwaarden voldaan is.An example is polling until specific conditions are met. U kunt een gewone timertrigger gebruiken voor een basisscenario, zoals een periodieke opschoningstaak, maar het interval is statisch en het beheer van de levensduur wordt complex.You can use a regular timer trigger to address a basic scenario, such as a periodic cleanup job, but its interval is static and managing instance lifetimes becomes complex. U kunt Durable Functions gebruiken om flexibele, terugkerende intervallen te creëren, de levensduur van taken te beheren en meerdere bewakingsprocessen maken vanuit één indeling.You can use Durable Functions to create flexible recurrence intervals, manage task lifetimes, and create multiple monitor processes from a single orchestration.

Een voorbeeld van het bewakingspatroon is om het eerdere asynchrone HTTP API-scenario om te keren.An example of the monitor pattern is to reverse the earlier async HTTP API scenario. In plaats van een eindpunt weer te geven waarmee een externe client een langdurige bewerking bewaakt, gebruikt de langdurige bewaking een extern eindpunt en wacht het tot de status verandert.Instead of exposing an endpoint for an external client to monitor a long-running operation, the long-running monitor consumes an external endpoint, and then waits for a state change.

Een diagram van het bewakingspatroon

Met enkele regels code kunt u Durable Functions gebruiken om meerdere bewakingen te maken die willekeurige eindpunten observeren.In a few lines of code, you can use Durable Functions to create multiple monitors that observe arbitrary endpoints. De bewakingen kunnen de uitvoering stopzetten wanneer er aan een voorwaarde is voldaan, of een andere functie kan de duurzame indelingsclient gebruiken om de bewakingen te beëindigen.The monitors can end execution when a condition is met, or another function can use the durable orchestration client to terminate the monitors. U kunt het wait-interval van een bewaking veranderen op basis van een specifieke voorwaarde (bijvoorbeeld exponentieel uitstel).You can change a monitor's wait interval based on a specific condition (for example, exponential backoff.)

Met de volgende code wordt een standaardbewaking geïmplementeerd:The following code implements a basic monitor:

[FunctionName("MonitorJobStatus")]
public static async Task Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    int jobId = context.GetInput<int>();
    int pollingInterval = GetPollingInterval();
    DateTime expiryTime = GetExpiryTime();

    while (context.CurrentUtcDateTime < expiryTime)
    {
        var jobStatus = await context.CallActivityAsync<string>("GetJobStatus", jobId);
        if (jobStatus == "Completed")
        {
            // Perform an action when a condition is met.
            await context.CallActivityAsync("SendAlert", machineId);
            break;
        }

        // Orchestration sleeps until this time.
        var nextCheck = context.CurrentUtcDateTime.AddSeconds(pollingInterval);
        await context.CreateTimer(nextCheck, CancellationToken.None);
    }

    // Perform more work here, or let the orchestration end.
}

Wanneer een verzoek ontvangen is, wordt er een nieuwe indelingsinstantie gemaakt voor die taak-id.When a request is received, a new orchestration instance is created for that job ID. De instantie controleert een status tot er aan een voorwaarde is voldaan en de lus wordt afgesloten.The instance polls a status until a condition is met and the loop is exited. Een duurzame timer controleert het polling-interval.A durable timer controls the polling interval. Vervolgens kan er meer werk worden uitgevoerd of kan de indeling beëindigd worden.Then, more work can be performed, or the orchestration can end. Wanneer nextCheck expiryTime overschrijdt eindigt de bewaking.When nextCheck exceeds expiryTime, the monitor ends.

Patroon #5: Menselijke tussenkomstPattern #5: Human interaction

Veel geautomatiseerde processen bevatten een menselijke tussenkomst.Many automated processes involve some kind of human interaction. Mensen betrekken bij een geautomatiseerd proces is lastig, want mensen zijn niet zo beschikbaar en responsief als cloudservices.Involving humans in an automated process is tricky because people aren't as highly available and as responsive as cloud services. Een geautomatiseerd proces kan deze tussenkomst mogelijk maken door time-outs en compensatielogica te gebruiken.An automated process might allow for this interaction by using timeouts and compensation logic.

Een goedkeuringsproces is een voorbeeld van een bedrijfsproces waar menselijke tussenkomst aan te pas komt.An approval process is an example of a business process that involves human interaction. Zo kan de goedkeuring van een manager vereist zijn voor een onkostennota die een bepaald bedrag overschrijdt.Approval from a manager might be required for an expense report that exceeds a certain dollar amount. Als de manager de onkostennota niet binnen de 72 uur goedkeurt (bijvoorbeeld omdat hij met vakantie is), dan wordt de escalatieprocedure opgestart om goedkeuring te krijgen van iemand anders (bijvoorbeeld de manager van de manager).If the manager doesn't approve the expense report within 72 hours (maybe the manager went on vacation), an escalation process kicks in to get the approval from someone else (perhaps the manager's manager).

Een diagram van het menselijke tussenkomstpatroon

U kunt het patroon in dit voorbeeld implementeren met behulp van een orchestrator-functie.You can implement the pattern in this example by using an orchestrator function. De orchestrator gebruikt een duurzame timer om goedkeuring te vragen.The orchestrator uses a durable timer to request approval. De orchestrator escaleert wanneer er een time-out optreedt.The orchestrator escalates if timeout occurs. De orchestrator wacht op een externe gebeurtenis zoals een melding die gegenereerd wordt door een menselijke tussenkomst.The orchestrator waits for an external event, such as a notification that's generated by a human interaction.

In deze voorbeelden wordt een goedkeuringsproces gemaakt om het menselijke tussenkomstpatroon te demonstreren:These examples create an approval process to demonstrate the human interaction pattern:

[FunctionName("ApprovalWorkflow")]
public static async Task Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    await context.CallActivityAsync("RequestApproval", null);
    using (var timeoutCts = new CancellationTokenSource())
    {
        DateTime dueTime = context.CurrentUtcDateTime.AddHours(72);
        Task durableTimeout = context.CreateTimer(dueTime, timeoutCts.Token);

        Task<bool> approvalEvent = context.WaitForExternalEvent<bool>("ApprovalEvent");
        if (approvalEvent == await Task.WhenAny(approvalEvent, durableTimeout))
        {
            timeoutCts.Cancel();
            await context.CallActivityAsync("ProcessApproval", approvalEvent.Result);
        }
        else
        {
            await context.CallActivityAsync("Escalate", null);
        }
    }
}

Roep context.CreateTimer aan om de duurzame timer te maken.To create the durable timer, call context.CreateTimer. De melding wordt ontvangen door context.WaitForExternalEvent.The notification is received by context.WaitForExternalEvent. Vervolgens wordt Task.WhenAny aangeroepen om te bepalen of er geëscaleerd wordt (time-out vindt eerst plaats) of dat de goedkeuring verwerkt wordt (de goedkeuring wordt ontvangen voor de time-out).Then, Task.WhenAny is called to decide whether to escalate (timeout happens first) or process the approval (the approval is received before timeout).

Een externe client kan de gebeurtenismelding afleveren aan een wachtende orchestrator-functie met behulp van de ingebouwde HTTP API's:An external client can deliver the event notification to a waiting orchestrator function by using the built-in HTTP APIs:

curl -d "true" http://localhost:7071/runtime/webhooks/durabletask/instances/{instanceId}/raiseEvent/ApprovalEvent -H "Content-Type: application/json"

Een gebeurtenis kan ook worden gegenereerd met behulp van de duurzame indelingsclient van een andere functie in dezelfde functie-app:An event can also be raised using the durable orchestration client from another function in the same function app:

[FunctionName("RaiseEventToOrchestration")]
public static async Task Run(
    [HttpTrigger] string instanceId,
    [DurableClient] IDurableOrchestrationClient client)
{
    bool isApproved = true;
    await client.RaiseEventAsync(instanceId, "ApprovalEvent", isApproved);
}

Patroon #6: Aggregator (stateful entiteiten)Pattern #6: Aggregator (stateful entities)

Het zesde patroon is het samenvoegen van gebeurtenisgegevens gedurende een bepaalde periode in één enkele, adresseerbare entiteit.The sixth pattern is about aggregating event data over a period of time into a single, addressable entity. In dit patroon kunnen de gegevens die samengevoegd worden afkomstig zijn van verschillende bronnen, geleverd worden in batches of verspreid worden over een lange periode.In this pattern, the data being aggregated may come from multiple sources, may be delivered in batches, or may be scattered over long-periods of time. De aggregator moet mogelijk actie ondernemen op de gebeurtenisgegevens wanneer die aankomen, en de externe clients moeten mogelijk de samengevoegde gegevens onderzoeken.The aggregator might need to take action on event data as it arrives, and external clients may need to query the aggregated data.

Aggregatordiagram

Wat de implementatie van dit patroon met normale, staatloze functies lastig maakt is dat het beheer van gelijktijdigheid erg moeilijk wordt.The tricky thing about trying to implement this pattern with normal, stateless functions is that concurrency control becomes a huge challenge. Niet alleen bewerken verschillende threads tegelijkertijd dezelfde gegevens, maar u dient er ook op te letten dat de aggregator slechts op één virtuele machine tegelijkertijd wordt uitgevoerd.Not only do you need to worry about multiple threads modifying the same data at the same time, you also need to worry about ensuring that the aggregator only runs on a single VM at a time.

U kunt Duurzame entiteiten gebruiken om dit patroon eenvoudig als een enkele functie te implementeren.You can use Durable entities to easily implement this pattern as a single function.

[FunctionName("Counter")]
public static void Counter([EntityTrigger] IDurableEntityContext ctx)
{
    int currentValue = ctx.GetState<int>();
    switch (ctx.OperationName.ToLowerInvariant())
    {
        case "add":
            int amount = ctx.GetInput<int>();
            ctx.SetState(currentValue + amount);
            break;
        case "reset":
            ctx.SetState(0);
            break;
        case "get":
            ctx.Return(currentValue);
            break;
    }
}

Duurzame entiteiten kunnen ook gemodelleerd worden als klassen in .NET.Durable entities can also be modeled as classes in .NET. Dit model kan handig zijn als de lijst met bewerkingen vaststaat en groot wordt.This model can be useful if the list of operations is fixed and becomes large. Het volgende voorbeeld is een equivalente implementatie van de Counter-entiteit met .NET-klassen en -methodes.The following example is an equivalent implementation of the Counter entity using .NET classes and methods.

public class Counter
{
    [JsonProperty("value")]
    public int CurrentValue { get; set; }

    public void Add(int amount) => this.CurrentValue += amount;

    public void Reset() => this.CurrentValue = 0;

    public int Get() => this.CurrentValue;

    [FunctionName(nameof(Counter))]
    public static Task Run([EntityTrigger] IDurableEntityContext ctx)
        => ctx.DispatchAsync<Counter>();
}

Clients kunnen bewerkingen in de wachtrij plaatsen (ook bekend als 'signalering') voor een entiteitsfunctie met behulp van de entiteitsclientbinding.Clients can enqueue operations for (also known as "signaling") an entity function using the entity client binding.

[FunctionName("EventHubTriggerCSharp")]
public static async Task Run(
    [EventHubTrigger("device-sensor-events")] EventData eventData,
    [DurableClient] IDurableEntityClient entityClient)
{
    var metricType = (string)eventData.Properties["metric"];
    var delta = BitConverter.ToInt32(eventData.Body, eventData.Body.Offset);

    // The "Counter/{metricType}" entity is created on-demand.
    var entityId = new EntityId("Counter", metricType);
    await entityClient.SignalEntityAsync(entityId, "add", delta);
}

Notitie

Dynamisch gegenereerde proxy's zijn ook beschikbaar in .NET om entiteiten op typebeveiligde wijze te signaleren. Dynamically generated proxies are also available in .NET for signaling entities in a type-safe way. Naast signaleren kunnen clients de status van een entiteitsfunctie ook opvragen met typebeveiligde methodes op de indelingsclientbinding.And in addition to signaling, clients can also query for the state of an entity function using type-safe methods on the orchestration client binding.

Entiteits functies zijn beschikbaar in Durable Functions 2,0 en hoger voor C#, java script en python.Entity functions are available in Durable Functions 2.0 and above for C#, JavaScript, and Python.

De technologieThe technology

Achter de schermen is de Durable Functions-extensie gebouwd op het Durable Task Framework, een opensource-bibliotheek in GitHub die gebruikt wordt om werkstromen te bouwen in code.Behind the scenes, the Durable Functions extension is built on top of the Durable Task Framework, an open-source library on GitHub that's used to build workflows in code. Net zoals Azure Functions de serverloze evolutie van Azure WebJobs is, is Durable Functions de serverloze evolutie van het Durable Task Framework.Like Azure Functions is the serverless evolution of Azure WebJobs, Durable Functions is the serverless evolution of the Durable Task Framework. Microsoft en andere organisaties gebruiken het Durable Task Framework om bedrijfskritieke processen te automatiseren.Microsoft and other organizations use the Durable Task Framework extensively to automate mission-critical processes. Het sluit naadloos aan op de serverloze Azure Functions-omgeving.It's a natural fit for the serverless Azure Functions environment.

CodebeperkingenCode constraints

Om betrouwbare en langdurige uitvoeringsgaranties te bieden, beschikken orchestrator-functies over een set coderegels die gevolg moeten worden.In order to provide reliable and long-running execution guarantees, orchestrator functions have a set of coding rules that must be followed. Zie het artikel Codebeperkingen voor de orchestrator-functie.For more information, see the Orchestrator function code constraints article.

BillingBilling

Durable Functions worden op dezelfde manier in rekening gebracht als Azure Functions.Durable Functions are billed the same as Azure Functions. Zie Prijzen voor Azure Functions voor meer informatie.For more information, see Azure Functions pricing. Wanneer u orchestrator-functies in het Verbruiksabonnement van Azure Functions uitvoert, dient u op enkele factureringseigenschappen te letten.When executing orchestrator functions in the Azure Functions Consumption plan, there are some billing behaviors to be aware of. Zie het artikel Durable Functions-facturering voor meer informatie hierover.For more information on these behaviors, see the Durable Functions billing article.

Duik er meteen inJump right in

U kunt in minder dan 10 minuten aan de slag gaan met Durable Functions door een van deze taalspecifieke quickstart-zelfstudies te volgen:You can get started with Durable Functions in under 10 minutes by completing one of these language-specific quickstart tutorials:

In deze quickstarts maakt en test u een lokale duurzame 'hallo wereld'-functie.In these quickstarts, you locally create and test a "hello world" durable function. Vervolgens publiceert u de functiecode op Azure.You then publish the function code to Azure. De functie die u maakt, organiseert en koppelt aanroepen naar andere functies.The function you create orchestrates and chains together calls to other functions.

Meer informatieLearn more

De volgende video laat de voordelen van Durable Functions zien:The following video highlights the benefits of Durable Functions:

Voor een uitgebreidere bespreking van Durable Functions en de onderliggende technologie bekijkt u de volgende video (deze focust op .NET, maar de concepten zijn ook van toepassing op andere ondersteunde talen):For a more in-depth discussion of Durable Functions and the underlying technology, see the following video (it's focused on .NET, but the concepts also apply to other supported languages):

Omdat Durable Functions een geavanceerde extensie voor Azure Functions is, is het niet geschikt voor alle toepassingen.Because Durable Functions is an advanced extension for Azure Functions, it isn't appropriate for all applications. Zie voor een vergelijking met andere Azure-technologieën Compare Azure Functions and Azure Logic Apps.For a comparison with other Azure orchestration technologies, see Compare Azure Functions and Azure Logic Apps.

Volgende stappenNext steps