Guide för att köra C# Azure Functions i den isolerade arbetsmodellen

Den här artikeln är en introduktion till att arbeta med Azure Functions i .NET med hjälp av den isolerade arbetsmodellen. Med den här modellen kan projektet rikta in sig på versioner av .NET oberoende av andra körningskomponenter. Information om specifika .NET-versioner som stöds finns i version som stöds.

Använd följande länkar för att komma igång direkt med att skapa .NET-isolerade arbetsmodellfunktioner.

Komma igång Begrepp Exempel

Mer information om hur du distribuerar ett isolerat arbetsmodellprojekt till Azure finns i Distribuera till Azure Functions.

Fördelar med den isolerade arbetsmodellen

Det finns två lägen där du kan köra .NET-klassbiblioteksfunktionerna: antingen i samma process som Functions-värdkörningen (pågår) eller i en isolerad arbetsprocess. När dina .NET-funktioner körs i en isolerad arbetsprocess kan du dra nytta av följande fördelar:

  • Färre konflikter: Eftersom dina funktioner körs i en separat process står sammansättningar som används i din app inte i konflikt med olika versioner av samma sammansättningar som används av värdprocessen.
  • Fullständig kontroll över processen: Du styr starten av appen, vilket innebär att du kan hantera de konfigurationer som används och mellanprogrammet startas.
  • Standardinmatning av beroenden: Eftersom du har fullständig kontroll över processen kan du använda aktuella .NET-beteenden för beroendeinmatning och införliva mellanprogram i funktionsappen.
  • .NET-versionsflexibilitet: Om du kör utanför värdprocessen kan dina funktioner köras på versioner av .NET som inte stöds internt av Functions-körningen, inklusive .NET Framework.

Om du har en befintlig C#-funktionsapp som körs i processen måste du migrera din app för att dra nytta av dessa fördelar. Mer information finns i Migrera .NET-appar från den pågående modellen till den isolerade arbetsmodellen.

En omfattande jämförelse mellan de två lägena finns i Skillnader mellan processer och isolera arbetsprocess .NET Azure Functions.

Versioner som stöds

Versioner av Functions-körningen stöder specifika versioner av .NET. Mer information om Functions-versioner finns i Översikt över Azure Functions-körningsversioner. Versionsstöd beror också på om dina funktioner körs i en process eller en isolerad arbetsprocess.

Kommentar

Information om hur du ändrar den Functions-körningsversion som används av funktionsappen finns i Visa och uppdatera den aktuella körningsversionen.

I följande tabell visas den högsta nivån av .NET eller .NET Framework som kan användas med en specifik version av Functions.

Funktionskörningsversion Isolerad arbetsmodell Processmodell5
Functions 4.x .NET 8.0
.NET 7.01
.NET 6.02
.NET Framework 4.83
.NET 6.02
Funktioner 1.x4 saknas .NET Framework 4.8

1 .NET 7 når slutet av det officiella stödet den 14 maj 2024.
2 .NET 6 når slutet av det officiella stödet den 12 november 2024.
3 Byggprocessen kräver också .NET SDK. 4 Support upphör för version 1.x av Azure Functions-körningen den 14 september 2026. Mer information finns i det här supportmeddelandet. Om du vill ha fortsatt fullständigt stöd bör du migrera dina appar till version 4.x.
5 Supporten upphör för den pågående modellen den 10 november 2026. Mer information finns i det här supportmeddelandet. Om du vill ha fortsatt fullständigt stöd bör du migrera dina appar till den isolerade arbetsmodellen.

För de senaste nyheterna om Azure Functions-versioner, inklusive borttagning av specifika äldre mindre versioner, övervakar du Azure App Service-meddelanden.

Projektstruktur

Ett .NET-projekt för Azure Functions med hjälp av den isolerade arbetsmodellen är i princip ett .NET-konsolappprojekt som riktar sig mot en .NET-körning som stöds. Följande är de grundläggande filer som krävs i alla .NET-isolerade projekt:

  • C#-projektfil (.csproj) som definierar projektet och beroenden.
  • Program.cs fil som är startpunkten för appen.
  • Alla kodfiler som definierar dina funktioner.
  • host.json fil som definierar konfiguration som delas av funktioner i projektet.
  • local.settings.json fil som definierar miljövariabler som används av projektet när den körs lokalt på datorn.

Fullständiga exempel finns i exempelprojektet .NET 8 och exempelprojektet .NET Framework 4.8.

Paketreferenser

Ett .NET-projekt för Azure Functions med hjälp av den isolerade arbetsmodellen använder en unik uppsättning paket för både kärnfunktioner och bindningstillägg.

Kärnpaket

Följande paket krävs för att köra .NET-funktionerna i en isolerad arbetsprocess:

Tilläggspaket

Eftersom .NET-isolerade arbetsprocessfunktioner använder olika bindningstyper kräver de en unik uppsättning paket med bindningstillägg.

Du hittar dessa tilläggspaket under Microsoft.Azure.Functions.Worker.Extensions.

Start och konfiguration

När du använder isolerade .NET-funktioner har du åtkomst till start av funktionsappen, som vanligtvis finns i Program.cs. Du ansvarar för att skapa och starta en egen värdinstans. Därför har du också direkt åtkomst till konfigurationspipelinen för din app. Med .NET Functions isolerade arbetsprocess kan du mycket enklare lägga till konfigurationer, mata in beroenden och köra ditt eget mellanprogram.

Följande kod visar ett exempel på en HostBuilder-pipeline :

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(s =>
    {
        s.AddApplicationInsightsTelemetryWorkerService();
        s.ConfigureFunctionsApplicationInsights();
        s.AddSingleton<IHttpResponderService, DefaultHttpResponderService>();
        s.Configure<LoggerFilterOptions>(options =>
        {
            // The Application Insights SDK adds a default logging filter that instructs ILogger to capture only Warning and more severe logs. Application Insights requires an explicit override.
            // Log levels can also be configured using appsettings.json. For more information, see https://learn.microsoft.com/en-us/azure/azure-monitor/app/worker-service#ilogger-logs
            LoggerFilterRule toRemove = options.Rules.FirstOrDefault(rule => rule.ProviderName
                == "Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider");

            if (toRemove is not null)
            {
                options.Rules.Remove(toRemove);
            }
        });
    })
    .Build();

Den här koden kräver using Microsoft.Extensions.DependencyInjection;.

Innan du anropar Build()HostBuilderbör du:

Om projektet är avsett för .NET Framework 4.8 måste du också lägga FunctionsDebugger.Enable(); till innan du skapar HostBuilder. Det bör vara den första raden i din Main() metod. Mer information finns i Felsökning när du riktar in dig på .NET Framework.

HostBuilder används för att skapa och returnera en helt initierad IHost instans som du kör asynkront för att starta funktionsappen.

await host.RunAsync();

Konfiguration

Metoden ConfigureFunctionsWorkerDefaults används för att lägga till de inställningar som krävs för att funktionsappen ska köras i en isolerad arbetsprocess, som innehåller följande funktioner:

  • Standarduppsättning med konverterare.
  • Ange JsonSerializerOptions som standard för att ignorera hölje för egenskapsnamn .
  • Integrera med Azure Functions-loggning.
  • Utdatabindning mellanprogram och funktioner.
  • Mellanprogram för funktionskörning.
  • Standardstöd för gRPC.
.ConfigureFunctionsWorkerDefaults()

Om du har åtkomst till pipelinen för värdverktyget kan du även ange appspecifika konfigurationer under initieringen. Du kan anropa metoden ConfigureAppConfigurationHostBuilder en eller flera gånger för att lägga till de konfigurationer som krävs av funktionsappen. Mer information om appkonfiguration finns i Konfiguration i ASP.NET Core.

Dessa konfigurationer gäller för din funktionsapp som körs i en separat process. Om du vill göra ändringar i funktionsvärden eller utlösaren och bindningskonfigurationen måste du fortfarande använda filen host.json.

Kommentar

Anpassade konfigurationskällor kan inte användas för konfiguration av utlösare och bindningar. Utlösar- och bindningskonfigurationen måste vara tillgänglig för Functions-plattformen och inte bara programkoden. Du kan ange den här konfigurationen via funktionerna för programinställningar, Key Vault-referenser eller appkonfigurationsreferenser .

Beroendeinmatning

Beroendeinmatning förenklas jämfört med .NET-in-processfunktioner, vilket kräver att du skapar en startklass för att registrera tjänster.

För en .NET-isolerad processapp använder du .NET-standardmetoden för att anropa ConfigureServices på värdverktyget och använder tilläggsmetoderna i IServiceCollection för att mata in specifika tjänster.

I följande exempel matas ett singleton-tjänstberoende in:

.ConfigureServices(services =>
{
    services.AddSingleton<IHttpResponderService, DefaultHttpResponderService>();
})

Den här koden kräver using Microsoft.Extensions.DependencyInjection;. Mer information finns i Beroendeinmatning i ASP.NET Core.

Registrera Azure-klienter

Beroendeinmatning kan användas för att interagera med andra Azure-tjänster. Du kan mata in klienter från Azure SDK för .NET med hjälp av Microsoft.Extensions.Azure-paketet . När du har installerat paketet registrerar du klienterna genom att anropa AddAzureClients() tjänstsamlingen i Program.cs. I följande exempel konfigureras en namngiven klient för Azure Blobs:

using Microsoft.Extensions.Azure;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices((hostContext, services) =>
    {
        services.AddAzureClients(clientBuilder =>
        {
            clientBuilder.AddBlobServiceClient(hostContext.Configuration.GetSection("MyStorageConnection"))
                .WithName("copierOutputBlob");
        });
    })
    .Build();

host.Run();

I följande exempel visas hur vi kan använda den här typen av registrering och SDK för att kopiera blobinnehåll som en dataström från en container till en annan med hjälp av en inmatad klient:

using Microsoft.Extensions.Azure;
using Microsoft.Extensions.Logging;

namespace MyFunctionApp
{
    public class BlobCopier
    {
        private readonly ILogger<BlobCopier> _logger;
        private readonly BlobContainerClient _copyContainerClient;

        public BlobCopier(ILogger<BlobCopier> logger, IAzureClientFactory<BlobServiceClient> blobClientFactory)
        {
            _logger = logger;
            _copyContainerClient = blobClientFactory.CreateClient("copierOutputBlob").GetBlobContainerClient("samples-workitems-copy");
            _copyContainerClient.CreateIfNotExists();
        }

        [Function("BlobCopier")]
        public async Task Run([BlobTrigger("samples-workitems/{name}", Connection = "MyStorageConnection")] Stream myBlob, string name)
        {
            await _copyContainerClient.UploadBlobAsync(name, myBlob);
            _logger.LogInformation($"Blob {name} copied!");
        }

    }
}

I ILogger<T> det här exemplet erhölls också via beroendeinmatning, så det registreras automatiskt. Mer information om konfigurationsalternativ för loggning finns i Loggning.

Dricks

Exemplet använde en literalsträng för namnet på klienten i både Program.cs och funktionen. Överväg i stället att använda en delad konstantsträng som definierats i funktionsklassen. Du kan till exempel lägga till public const string CopyStorageClientName = nameof(_copyContainerClient); och sedan referera till BlobCopier.CopyStorageClientName på båda platserna. Du kan på liknande sätt definiera konfigurationsavsnittets namn med funktionen i stället för i Program.cs.

Mellanprogram

.NET isolerad har också stöd för registrering av mellanprogram genom att använda en modell som liknar den som finns i ASP.NET. Den här modellen ger dig möjlighet att mata in logik i anropspipelinen och köra före och efter-funktionerna.

Metoden ConfigureFunctionsWorkerDefaults-tillägg har en överlagring som gör att du kan registrera ditt eget mellanprogram, som du kan se i följande exempel.

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults(workerApplication =>
    {
        // Register our custom middlewares with the worker

        workerApplication.UseMiddleware<ExceptionHandlingMiddleware>();

        workerApplication.UseMiddleware<MyCustomMiddleware>();

        workerApplication.UseWhen<StampHttpHeaderMiddleware>((context) =>
        {
            // We want to use this middleware only for http trigger invocations.
            return context.FunctionDefinition.InputBindings.Values
                          .First(a => a.Type.EndsWith("Trigger")).Type == "httpTrigger";
        });
    })
    .Build();

Tilläggsmetoden UseWhen kan användas för att registrera ett mellanprogram som körs villkorligt. Du måste skicka ett predikat till den här metoden som returnerar ett booleskt värde och mellanprogrammet deltar i pipelinen för anropsbearbetning när returvärdet för predikatet är true.

Följande tilläggsmetoder i FunctionContext gör det enklare att arbeta med mellanprogram i den isolerade modellen.

Metod beskrivning
GetHttpRequestDataAsync Hämtar instansen när den HttpRequestData anropas av en HTTP-utlösare. Den här metoden returnerar en instans av ValueTask<HttpRequestData?>, vilket är användbart när du vill läsa meddelandedata, till exempel begärandehuvuden och cookies.
GetHttpResponseData Hämtar instansen när den HttpResponseData anropas av en HTTP-utlösare.
GetInvocationResult Hämtar en instans av InvocationResult, som representerar resultatet av den aktuella funktionskörningen. Använd egenskapen Value för att hämta eller ange värdet efter behov.
GetOutputBindings Hämtar utdatabindningsposterna för den aktuella funktionskörningen. Varje post i resultatet av den här metoden är av typen OutputBindingData. Du kan använda egenskapen Value för att hämta eller ange värdet efter behov.
BindInputAsync Binder ett indatabindningsobjekt för den begärda BindingMetadata instansen. Du kan till exempel använda den här metoden när du har en funktion med en BlobInput indatabindning som måste användas av mellanprogrammet.

Det här är ett exempel på en implementering av mellanprogram som läser instansen HttpRequestData och uppdaterar instansen HttpResponseData under funktionskörningen:

internal sealed class StampHttpHeaderMiddleware : IFunctionsWorkerMiddleware
{
    public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
    {
        var requestData = await context.GetHttpRequestDataAsync();

        string correlationId;
        if (requestData!.Headers.TryGetValues("x-correlationId", out var values))
        {
            correlationId = values.First();
        }
        else
        {
            correlationId = Guid.NewGuid().ToString();
        }

        await next(context);

        context.GetHttpResponseData()?.Headers.Add("x-correlationId", correlationId);
    }
}

Det här mellanprogrammet söker efter förekomsten av ett specifikt begärandehuvud (x-correlationId) och när det finns det använder huvudvärdet för att stämpla ett svarshuvud. Annars genererar det ett nytt GUID-värde och använder det för att stämpla svarshuvudet. Ett mer komplett exempel på hur du använder anpassade mellanprogram i funktionsappen finns i referensexemplet för anpassade mellanprogram.

Anpassa JSON-serialisering

Den isolerade arbetsmodellen använder System.Text.Json som standard. Du kan anpassa serialiserarens beteende genom att konfigurera tjänster som en del av filen Program.cs . I följande exempel visas detta med hjälp av ConfigureFunctionsWebApplication, men det fungerar också för ConfigureFunctionsWorkerDefaults:

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication((IFunctionsWorkerApplicationBuilder builder) =>
    {
        builder.Services.Configure<JsonSerializerOptions>(jsonSerializerOptions =>
        {
            jsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
            jsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
            jsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;

            // override the default value
            jsonSerializerOptions.PropertyNameCaseInsensitive = false;
        });
    })
    .Build();

Du kanske i stället vill använda JSON.NET (Newtonsoft.Json) för serialisering. Det gör du genom att Microsoft.Azure.Core.NewtonsoftJson installera paketet. I din tjänstregistrering skulle du sedan omtilldela Serializer egenskapen i konfigurationen WorkerOptions . I följande exempel visas detta med hjälp av ConfigureFunctionsWebApplication, men det fungerar också för ConfigureFunctionsWorkerDefaults:

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication((IFunctionsWorkerApplicationBuilder builder) =>
    {
        builder.Services.Configure<WorkerOptions>(workerOptions =>
        {
            var settings = NewtonsoftJsonObjectSerializer.CreateJsonSerializerSettings();
            settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            settings.NullValueHandling = NullValueHandling.Ignore;

            workerOptions.Serializer = new NewtonsoftJsonObjectSerializer(settings);
        });
    })
    .Build();

Metoder som identifieras som funktioner

En funktionsmetod är en offentlig metod för en offentlig klass med ett Function attribut som tillämpas på metoden och ett utlösarattribut som tillämpas på en indataparameter, enligt följande exempel:

[Function(nameof(QueueFunction))]
[QueueOutput("output-queue")]
public string[] Run([QueueTrigger("input-queue")] Album myQueueItem, FunctionContext context)

Utlösarattributet anger utlösartypen och binder indata till en metodparameter. Den tidigare exempelfunktionen utlöses av ett kömeddelande och kömeddelandet skickas till metoden i parametern myQueueItem .

Attributet Function markerar metoden som en funktionsinmatningspunkt. Namnet måste vara unikt i ett projekt, börja med en bokstav och endast innehålla bokstäver, siffror, _och -, upp till 127 tecken långa. Projektmallar skapar ofta en metod med namnet Run, men metodnamnet kan vara valfritt giltigt C#-metodnamn. Metoden måste vara en offentlig medlem i en offentlig klass. Det bör vanligtvis vara en instansmetod så att tjänster kan skickas via beroendeinmatning.

Funktionsparametrar

Här är några av de parametrar som du kan inkludera som en del av en funktionsmetodsignatur:

  • Bindningar, som markeras som sådana genom att dekorera parametrarna som attribut. Funktionen måste innehålla exakt en utlösarparameter.
  • Ett körningskontextobjekt som innehåller information om det aktuella anropet.
  • En annulleringstoken som används för en korrekt avstängning.

Körningskontext

.NET isolerad skickar ett FunctionContext-objekt till dina funktionsmetoder. Med det här objektet kan du få en ILogger instans att skriva till loggarna genom att anropa metoden GetLogger och ange en categoryName sträng. Du kan använda den här kontexten för att hämta en ILogger utan att behöva använda beroendeinmatning. Mer information finns i Loggning.

Annulleringstoken

En funktion kan acceptera parametern CancellationToken , vilket gör att operativsystemet kan meddela koden när funktionen är på väg att avslutas. Du kan använda det här meddelandet för att se till att funktionen inte avslutas oväntat på ett sätt som lämnar data i ett inkonsekvent tillstånd.

Annulleringstoken stöds i .NET-funktioner när de körs i en isolerad arbetsprocess. I följande exempel uppstår ett undantag när en begäran om annullering tas emot:

[Function(nameof(ThrowOnCancellation))]
public async Task ThrowOnCancellation(
    [EventHubTrigger("sample-workitem-1", Connection = "EventHubConnection")] string[] messages,
    FunctionContext context,
    CancellationToken cancellationToken)
{
    _logger.LogInformation("C# EventHub {functionName} trigger function processing a request.", nameof(ThrowOnCancellation));

    foreach (var message in messages)
    {
        cancellationToken.ThrowIfCancellationRequested();
        await Task.Delay(6000); // task delay to simulate message processing
        _logger.LogInformation("Message '{msg}' was processed.", message);
    }
}

I följande exempel utförs rensningsåtgärder när en begäran om annullering tas emot:

[Function(nameof(HandleCancellationCleanup))]
public async Task HandleCancellationCleanup(
    [EventHubTrigger("sample-workitem-2", Connection = "EventHubConnection")] string[] messages,
    FunctionContext context,
    CancellationToken cancellationToken)
{
    _logger.LogInformation("C# EventHub {functionName} trigger function processing a request.", nameof(HandleCancellationCleanup));

    foreach (var message in messages)
    {
        if (cancellationToken.IsCancellationRequested)
        {
            _logger.LogInformation("A cancellation token was received, taking precautionary actions.");
            // Take precautions like noting how far along you are with processing the batch
            _logger.LogInformation("Precautionary activities complete.");
            break;
        }

        await Task.Delay(6000); // task delay to simulate message processing
        _logger.LogInformation("Message '{msg}' was processed.", message);
    }
}

Bindningar

Bindningar definieras med hjälp av attribut för metoder, parametrar och returtyper. Bindningar kan tillhandahålla data som strängar, matriser och serialiserbara typer, till exempel vanliga gamla klassobjekt (POCO: er). För vissa bindningstillägg kan du också binda till tjänstspecifika typer som definierats i tjänst-SDK:er.

Http-utlösare finns i avsnittet HTTP-utlösare .

En fullständig uppsättning referensexempel med utlösare och bindningar med isolerade arbetsprocessfunktioner finns i referensexemplet för bindningstillägg.

Indatabindningar

En funktion kan ha noll eller fler indatabindningar som kan skicka data till en funktion. Precis som utlösare definieras indatabindningar genom att ett bindningsattribut tillämpas på en indataparameter. När funktionen körs försöker körningen hämta data som anges i bindningen. De data som begärs är ofta beroende av information som tillhandahålls av utlösaren med hjälp av bindningsparametrar.

Utdatabindningar

Om du vill skriva till en utdatabindning måste du använda ett utdatabindningsattribut för funktionsmetoden, som definierar hur du skriver till den bundna tjänsten. Värdet som returneras av metoden skrivs till utdatabindningen. I följande exempel skrivs till exempel ett strängvärde till en meddelandekö med namnet med hjälp av en utdatabindning output-queue :

[Function(nameof(QueueFunction))]
[QueueOutput("output-queue")]
public string[] Run([QueueTrigger("input-queue")] Album myQueueItem, FunctionContext context)
{
    // Use a string array to return more than one message.
    string[] messages = {
        $"Album name = {myQueueItem.Name}",
        $"Album songs = {myQueueItem.Songs.ToString()}"};

    _logger.LogInformation("{msg1},{msg2}", messages[0], messages[1]);

    // Queue Output messages
    return messages;
}

Flera utdatabindningar

Data som skrivs till en utdatabindning är alltid funktionens returvärde. Om du behöver skriva till mer än en utdatabindning måste du skapa en anpassad returtyp. Den här returtypen måste ha utdatabindningsattributet tillämpat på en eller flera egenskaper för klassen. Följande exempel från en HTTP-utlösare skriver till både HTTP-svaret och en köutdatabindning:

public static class MultiOutput
{
    [Function(nameof(MultiOutput))]
    public static MyOutputType Run([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequestData req,
        FunctionContext context)
    {
        var response = req.CreateResponse(HttpStatusCode.OK);
        response.WriteString("Success!");

        string myQueueOutput = "some output";

        return new MyOutputType()
        {
            Name = myQueueOutput,
            HttpResponse = response
        };
    }
}

public class MyOutputType
{
    [QueueOutput("myQueue")]
    public string Name { get; set; }

    public HttpResponseData HttpResponse { get; set; }
}

Svaret från en HTTP-utlösare betraktas alltid som utdata, så ett returvärdeattribut krävs inte.

SDK-typer

För vissa tjänstspecifika bindningstyper kan bindningsdata tillhandahållas med hjälp av typer från tjänst-SDK:er och ramverk. Dessa ger mer funktioner utöver vad en serialiserad sträng eller vanligt gammalt CLR-objekt (POCO) kan erbjuda. Om du vill använda de nyare typerna måste projektet uppdateras för att kunna använda nyare versioner av kärnberoenden.

Dependency Versionskrav
Microsoft.Azure.Functions.Worker 1.18.0 eller senare
Microsoft.Azure.Functions.Worker.Sdk 1.13.0 eller senare

När du testar SDK-typer lokalt på datorn måste du också använda Azure Functions Core Tools, version 4.0.5000 eller senare. Du kan kontrollera din aktuella version med hjälp av func version kommandot .

Varje utlösare och bindningstillägg har också ett eget krav på lägsta version, vilket beskrivs i tilläggsreferensartiklarna. Följande tjänstspecifika bindningar tillhandahåller SDK-typer:

Tjänst Utlösare Indatabindning Utdatabindning
Azure Blobs Allmänt tillgänglig Allmänt tillgänglig SDK-typer rekommenderas inte.1
Azure Queues Allmänt tillgänglig Indatabindning finns inte SDK-typer rekommenderas inte.1
Azure Service Bus Allmänt tillgänglig Indatabindning finns inte SDK-typer rekommenderas inte.1
Azure Event Hubs Allmänt tillgänglig Indatabindning finns inte SDK-typer rekommenderas inte.1
Azure Cosmos DB SDK-typer som inte används2 Allmänt tillgänglig SDK-typer rekommenderas inte.1
Azure-tabeller Utlösaren finns inte Allmänt tillgänglig SDK-typer rekommenderas inte.1
Azure Event Grid Allmänt tillgänglig Indatabindning finns inte SDK-typer rekommenderas inte.1

1 För utdatascenarier där du använder en SDK-typ bör du skapa och arbeta med SDK-klienter direkt i stället för att använda en utdatabindning. Se Registrera Azure-klienter för ett exempel på beroendeinmatning.

2 Cosmos DB-utlösaren använder Azure Cosmos DB-ändringsflödet och exponerar ändringsflödesobjekt som JSON-serialiserbara typer. Avsaknaden av SDK-typer är avsiktlig för det här scenariot.

Kommentar

När du använder bindningsuttryck som förlitar sig på utlösardata kan SDK-typer för själva utlösaren inte användas.

HTTP-utlösare

MED HTTP-utlösare kan en funktion anropas av en HTTP-begäran. Det finns två olika metoder som kan användas:

  • En ASP.NET Core-integreringsmodell som använder begrepp som är bekanta för ASP.NET Core-utvecklare
  • En inbyggd modell som inte kräver extra beroenden och använder anpassade typer för HTTP-begäranden och svar. Den här metoden bibehålls för bakåtkompatibilitet med tidigare .NET-isolerade arbetsappar.

ASP.NET Core-integrering

Det här avsnittet visar hur du arbetar med underliggande HTTP-begärande- och svarsobjekt med hjälp av typer från ASP.NET Core, inklusive HttpRequest, HttpResponse och IActionResult. Den här modellen är inte tillgänglig för appar som riktar sig till .NET Framework, som i stället ska använda den inbyggda modellen.

Kommentar

Alla funktioner i ASP.NET Core exponeras inte av den här modellen. Mer specifikt är pipelinen och routningsfunktionerna för ASP.NET Core-mellanprogram inte tillgängliga. ASP.NET Core-integreringen kräver att du använder uppdaterade paket.

Så här aktiverar du ASP.NET Core-integrering för HTTP:

  1. Lägg till en referens i projektet till paketet Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore , version 1.0.0 eller senare.

  2. Uppdatera projektet så att det använder dessa specifika paketversioner:

  3. Program.cs I filen uppdaterar du konfigurationen för värdverktyget så att den används ConfigureFunctionsWebApplication() i stället för ConfigureFunctionsWorkerDefaults(). I följande exempel visas en minimal konfiguration utan andra anpassningar:

    using Microsoft.Extensions.Hosting;
    using Microsoft.Azure.Functions.Worker;
    
    var host = new HostBuilder()
        .ConfigureFunctionsWebApplication()
        .Build();
    
    host.Run();
    
  4. Uppdatera befintliga HTTP-utlösta funktioner så att de använder ASP.NET Core-typerna. Det här exemplet visar standarden HttpRequest och en IActionResult som används för en enkel "hello, world"-funktion:

    [Function("HttpFunction")]
    public IActionResult Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req)
    {
        return new OkObjectResult($"Welcome to Azure Functions, {req.Query["name"]}!");
    }
    

Inbyggd HTTP-modell

I den inbyggda modellen översätter systemet det inkommande HTTP-begärandemeddelandet till ett HttpRequestData-objekt som skickas till funktionen. Det här objektet innehåller data från begäran, inklusive Headers, Cookies, Identities, URLoch eventuellt ett meddelande Body. Det här objektet är en representation av HTTP-begäran men är inte direkt ansluten till den underliggande HTTP-lyssnaren eller det mottagna meddelandet.

På samma sätt returnerar funktionen ett HttpResponseData-objekt , som tillhandahåller data som används för att skapa HTTP-svaret, inklusive meddelandet StatusCode, Headersoch eventuellt ett meddelande Body.

I följande exempel visas användningen av HttpRequestData och HttpResponseData:

[Function(nameof(HttpFunction))]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequestData req,
    FunctionContext executionContext)
{
    var logger = executionContext.GetLogger(nameof(HttpFunction));
    logger.LogInformation("message logged");

    var response = req.CreateResponse(HttpStatusCode.OK);
    response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
    response.WriteString("Welcome to .NET isolated worker !!");

    return response;
}

Loggning

I .NET isolerad kan du skriva till loggar med hjälp av en eller ILogger -ILogger<T>instans. Loggern kan hämtas genom beroendeinmatning av en ILogger<T> eller av en ILoggerFactory:

public class MyFunction {
    
    private readonly ILogger<MyFunction> _logger;
    
    public MyFunction(ILogger<MyFunction> logger) {
        _logger = logger;
    }
    
    [Function(nameof(MyFunction))]
    public void Run([BlobTrigger("samples-workitems/{name}", Connection = "")] string myBlob, string name)
    {
        _logger.LogInformation($"C# Blob trigger function Processed blob\n Name: {name} \n Data: {myBlob}");
    }

}

Loggern kan också hämtas från ett FunctionContext-objekt som skickas till din funktion. Anropa metoden GetLogger<T> eller GetLogger och skicka ett strängvärde som är namnet på den kategori där loggarna skrivs. Kategorin är vanligtvis namnet på den specifika funktion som loggarna skrivs från. Mer information om kategorier finns i övervakningsartikeln.

Använd metoderna ILogger<T> för och ILogger för att skriva olika loggnivåer, till exempel LogWarning eller LogError. Mer information om loggnivåer finns i övervakningsartikeln. Du kan anpassa loggnivåerna för komponenter som läggs till i koden genom att registrera filter som en del av konfigurationen HostBuilder :

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(services =>
    {
        // Registers IHttpClientFactory.
        // By default this sends a lot of Information-level logs.
        services.AddHttpClient();
    })
    .ConfigureLogging(logging =>
    {
        // Disable IHttpClientFactory Informational logs.
        // Note -- you can also remove the handler that does the logging: https://github.com/aspnet/HttpClientFactory/issues/196#issuecomment-432755765 
        logging.AddFilter("System.Net.Http.HttpClient", LogLevel.Warning);
    })
    .Build();

Som en del av konfigurationen av appen i Program.cskan du också definiera beteendet för hur fel visas i loggarna. Som standard kan undantag som genereras av koden omslutas i en RpcException. Om du vill ta bort det här extra lagret anger du EnableUserCodeException egenskapen till "true" som en del av konfigurationen av byggaren:

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults(builder => {}, options =>
    {
        options.EnableUserCodeException = true;
    })
    .Build();

Programinsikter

Du kan konfigurera ditt isolerade processprogram så att loggar skickas direkt till Application Insights. Det här beteendet ersätter standardbeteendet för att vidarebefordra loggar via värden och rekommenderas eftersom det ger dig kontroll över hur dessa loggar genereras.

Installera paket

Om du vill skriva loggar direkt till Application Insights från din kod lägger du till referenser till dessa paket i projektet:

Du kan köra följande kommandon för att lägga till dessa referenser i projektet:

dotnet add package Microsoft.ApplicationInsights.WorkerService
dotnet add package Microsoft.Azure.Functions.Worker.ApplicationInsights

Konfigurera start

När paketen är installerade måste du anropa AddApplicationInsightsTelemetryWorkerService() och ConfigureFunctionsApplicationInsights() under tjänstkonfigurationen i Program.cs filen, som i det här exemplet:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
    
var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(services => {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
    })
    .Build();

host.Run();

Anropet till lägger till ConfigureFunctionsApplicationInsights() en ITelemetryModule, som lyssnar på en Functions-definierad ActivitySource. Detta skapar den beroendetelemetri som krävs för att stödja distribuerad spårning. Mer information om AddApplicationInsightsTelemetryWorkerService() och hur du använder det finns i Application Insights för Worker Service-program.

Hantera loggnivåer

Viktigt!

Functions-värden och den isolerade processarbetaren har separat konfiguration för loggnivåer osv. Alla Application Insights-konfigurationer i host.json påverkar inte loggningen från arbetaren, och på samma sätt påverkar konfigurationen som görs i arbetskoden inte loggningen från värden. Du måste tillämpa ändringar på båda platserna om ditt scenario kräver anpassning i båda lagren.

Resten av programmet fortsätter att fungera med ILogger och ILogger<T>. Men som standard lägger Application Insights SDK till ett loggningsfilter som instruerar loggarna att endast samla in varningar och allvarligare loggar. Om du vill inaktivera det här beteendet tar du bort filterregeln som en del av tjänstkonfigurationen:

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(services => {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
    })
    .ConfigureLogging(logging =>
    {
        logging.Services.Configure<LoggerFilterOptions>(options =>
        {
            LoggerFilterRule defaultRule = options.Rules.FirstOrDefault(rule => rule.ProviderName
                == "Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider");
            if (defaultRule is not null)
            {
                options.Rules.Remove(defaultRule);
            }
        });
    })
    .Build();

host.Run();

Prestandaoptimering

I det här avsnittet beskrivs alternativ som du kan aktivera för att förbättra prestanda kring kallstart.

I allmänhet bör appen använda de senaste versionerna av sina kärnberoenden. Du bör åtminstone uppdatera projektet på följande sätt:

  1. Uppgradera Microsoft.Azure.Functions.Worker till version 1.19.0 eller senare.
  2. Uppgradera Microsoft.Azure.Functions.Worker.Sdk till version 1.16.4 eller senare.
  3. Lägg till en ramverksreferens till Microsoft.AspNetCore.App, såvida inte din app riktar in sig på .NET Framework.

Följande kodfragment visar den här konfigurationen i kontexten för en projektfil:

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.21.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.16.4" />
  </ItemGroup>

Platshållare

Platshållare är en plattformsfunktion som förbättrar kallstarten för appar som riktar sig till .NET 6 eller senare. Om du vill använda den här optimeringen måste du uttryckligen aktivera platshållare med hjälp av följande steg:

  1. Uppdatera projektkonfigurationen så att den använder de senaste beroendeversionerna enligt beskrivningen i föregående avsnitt.

  2. Ange programinställningen WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED till 1, vilket du kan göra med hjälp av det här kommandot az functionapp config appsettings set :

    az functionapp config appsettings set -g <groupName> -n <appName> --settings 'WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED=1'
    

    I det här exemplet ersätter du <groupName> med namnet på resursgruppen och ersätter <appName> med namnet på funktionsappen.

  3. Kontrollera att netFrameworkVersion funktionsappens egenskap matchar projektets målramverk, som måste vara .NET 6 eller senare. Du kan göra detta med hjälp av kommandot az functionapp config set :

    az functionapp config set -g <groupName> -n <appName> --net-framework-version <framework>
    

    I det här exemplet ersätter <framework> du även med lämplig versionssträng, till exempel v8.0, v7.0eller v6.0, enligt din .NET-målversion.

  4. Kontrollera att funktionsappen är konfigurerad för att använda en 64-bitarsprocess, vilket du kan göra med hjälp av det här kommandot az functionapp config set :

    az functionapp config set -g <groupName> -n <appName> --use-32bit-worker-process false
    

Viktigt!

När du anger WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED till 1måste alla andra funktionsappkonfigurationer vara korrekt inställda. Annars kan funktionsappen misslyckas med att starta.

Optimerad köre

Funktionsexekutor är en komponent i plattformen som gör att anrop körs. En optimerad version av den här komponenten är aktiverad som standard från och med version 1.16.2 av SDK: et. Ingen annan konfiguration krävs.

ReadyToRun

Du kan kompilera funktionsappen som ReadyToRun-binärfiler. ReadyToRun är en form av kompilering i förväg som kan förbättra startprestanda för att minska effekten av kalla starter när du kör i en förbrukningsplan. ReadyToRun är tillgängligt i .NET 6 och senare versioner och kräver version 4.0 eller senare av Azure Functions-körningen.

ReadyToRun kräver att du skapar projektet mot körningsarkitekturen för värdappen. Om dessa inte är justerade får din app ett fel vid start. Välj din körningsidentifierare från den här tabellen:

Operativsystem Appen är 32-bitars1 Körningsidentifierare
Windows Sant win-x86
Windows Falsk win-x64
Linux Sant N/A (stöds inte)
Linux Falsk linux-x64

1 Endast 64-bitarsappar är berättigade till vissa andra prestandaoptimeringar.

Om du vill kontrollera om Windows-appen är 32-bitars eller 64-bitars kan du köra följande CLI-kommando och ersätta <group_name> med namnet på resursgruppen och <app_name> med namnet på ditt program. Ett utdata av "true" anger att appen är 32-bitars och "false" anger 64-bitars.

 az functionapp config show -g <group_name> -n <app_name> --query "use32BitWorkerProcess"

Du kan ändra programmet till 64-bitars med följande kommando med samma ersättningar:

az functionapp config set -g <group_name> -n <app_name> --use-32bit-worker-process false`

Om du vill kompilera projektet som ReadyToRun uppdaterar du projektfilen genom att lägga till elementen <PublishReadyToRun> och <RuntimeIdentifier> . I följande exempel visas en konfiguration för publicering till en Windows 64-bitars funktionsapp.

<PropertyGroup>
  <TargetFramework>net8.0</TargetFramework>
  <AzureFunctionsVersion>v4</AzureFunctionsVersion>
  <RuntimeIdentifier>win-x64</RuntimeIdentifier>
  <PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>

Om du inte vill ange <RuntimeIdentifier> som en del av projektfilen kan du också konfigurera detta som en del av själva publiceringsgesten. Med en Windows 64-bitars funktionsapp skulle till exempel .NET CLI-kommandot vara:

dotnet publish --runtime win-x64

I Visual Studio ska alternativet Målkörning i publiceringsprofilen anges till rätt körningsidentifierare. När värdet för Portabel är inställt på standardvärdet används inte ReadyToRun.

Distribuera till Azure Functions

När du distribuerar funktionskodprojektet till Azure måste det köras i antingen en funktionsapp eller i en Linux-container. Funktionsappen och andra nödvändiga Azure-resurser måste finnas innan du distribuerar koden.

Du kan också distribuera funktionsappen i en Linux-container. Mer information finns i Arbeta med containrar och Azure Functions.

Skapa Azure-resurser

Du kan skapa din funktionsapp och andra nödvändiga resurser i Azure med någon av följande metoder:

  • Visual Studio: Visual Studio kan skapa resurser åt dig under kodpubliceringsprocessen.
  • Visual Studio Code: Visual Studio Code kan ansluta till din prenumeration, skapa de resurser som behövs av din app och sedan publicera koden.
  • Azure CLI: Du kan använda Azure CLI för att skapa de resurser som krävs i Azure.
  • Azure PowerShell: Du kan använda Azure PowerShell för att skapa de resurser som krävs i Azure.
  • Distributionsmallar: Du kan använda ARM-mallar och Bicep-filer för att automatisera distributionen av nödvändiga resurser till Azure. Kontrollera att mallen innehåller nödvändiga inställningar.
  • Azure-portalen: Du kan skapa de resurser som krävs i Azure-portalen.

Publicera kodprojekt

När du har skapat din funktionsapp och andra nödvändiga resurser i Azure kan du distribuera kodprojektet till Azure med någon av följande metoder:

Mer information finns i Distributionstekniker i Azure Functions.

Distributionskrav

Det finns några krav för att köra .NET-funktioner i den isolerade arbetsmodellen i Azure, beroende på operativsystemet:

  • FUNCTIONS_WORKER_RUNTIME måste anges till värdet dotnet-isolated.
  • netFrameworkVersion måste anges till önskad version.

När du skapar din funktionsapp i Azure med hjälp av metoderna i föregående avsnitt läggs de här nödvändiga inställningarna till åt dig. När du skapar dessa resurser med hjälp av ARM-mallar eller Bicep-filer för automatisering måste du ange dem i mallen.

Felsökning

När du kör lokalt med Visual Studio eller Visual Studio Code kan du felsöka ditt .NET-isolerade arbetsprojekt som vanligt. Det finns dock två felsökningsscenarier som inte fungerar som förväntat.

Fjärrfelsökning med Visual Studio

Eftersom din isolerade arbetsprocessapp körs utanför Functions-körningen måste du koppla fjärrfelsökaren till en separat process. Mer information om felsökning med Hjälp av Visual Studio finns i Fjärrfelsökning.

Felsökning när du riktar in dig på .NET Framework

Om ditt isolerade projekt är avsett för .NET Framework 4.8 kräver det aktuella förhandsgranskningsomfånget manuella steg för att aktivera felsökning. De här stegen krävs inte om du använder ett annat målramverk.

Din app bör börja med ett anrop till FunctionsDebugger.Enable(); som sin första åtgärd. Detta inträffar i Main() metoden innan en HostBuilder initieras. Filen Program.cs bör se ut ungefär så här:

using System;
using System.Diagnostics;
using Microsoft.Extensions.Hosting;
using Microsoft.Azure.Functions.Worker;
using NetFxWorker;

namespace MyDotnetFrameworkProject
{
    internal class Program
    {
        static void Main(string[] args)
        {
            FunctionsDebugger.Enable();

            var host = new HostBuilder()
                .ConfigureFunctionsWorkerDefaults()
                .Build();

            host.Run();
        }
    }
}

Därefter måste du ansluta till processen manuellt med hjälp av ett .NET Framework-felsökningsprogram. Visual Studio gör inte detta automatiskt för .NET Framework-appar för isolerad arbetsprocess ännu, och åtgärden "Starta felsökning" bör undvikas.

I projektkatalogen (eller dess utdatakatalog) kör du:

func host start --dotnet-isolated-debug

Detta startar din arbetsprocess och processen avslutas med följande meddelande:

Azure Functions .NET Worker (PID: <process id>) initialized in debug mode. Waiting for debugger to attach...

Var <process id> finns ID:t för din arbetsprocess. Nu kan du använda Visual Studio för att manuellt ansluta till processen. Anvisningar om den här åtgärden finns i Så här kopplar du till en process som körs.

När felsökningsprogrammet har kopplats återupptas processkörningen och du kan felsöka.

Förhandsgranska .NET-versioner

Innan en allmänt tillgänglig version kan en .NET-version släppas i ett förhandsversions - eller Go-live-tillstånd . Mer information om dessa tillstånd finns i den officiella supportpolicyn för .NET.

Det kan vara möjligt att rikta in sig på en viss version från ett lokalt Functions-projekt, men funktionsappar som finns i Azure kanske inte har den versionen tillgänglig. Azure Functions kan bara användas med förhandsversioner eller Go-live-versioner som anges i det här avsnittet.

Azure Functions fungerar för närvarande inte med någon "förhandsversion" eller "Go-live" .NET-versioner. En lista över allmänt tillgängliga versioner som du kan använda finns i Versioner som stöds.

Använda en förhandsversion av .NET SDK

Om du vill använda Azure Functions med en förhandsversion av .NET måste du uppdatera projektet genom att:

  1. Installera relevant .NET SDK-version i din utveckling
  2. Ändra inställningen TargetFramework i .csproj filen

När du distribuerar till en funktionsapp i Azure måste du också se till att ramverket görs tillgängligt för appen. Om du vill göra det i Windows kan du använda följande CLI-kommando. Ersätt <groupName> med namnet på resursgruppen och ersätt <appName> med namnet på funktionsappen. Ersätt <framework> med lämplig versionssträng, till exempel v8.0.

az functionapp config set -g <groupName> -n <appName> --net-framework-version <framework>

Överväganden för att använda förhandsversioner av .NET

Tänk på följande när du använder Functions med förhandsversioner av .NET:

  • När du skapar dina funktioner i Visual Studio måste du använda Visual Studio Preview, som har stöd för att skapa Azure Functions-projekt med .NET preview SDK:er.

  • Kontrollera att du har de senaste Functions-verktygen och mallarna. Så här uppdaterar du dina verktyg:

    1. Gå till Verktygsalternativ> och välj Azure Functions under Projekt och lösningar.
    2. Välj Sök efter uppdateringar och installera uppdateringar enligt anvisningarna.
  • Under en förhandsversionsperiod kan utvecklingsmiljön ha en nyare version av .NET-förhandsversionen än den värdbaserade tjänsten. Detta kan göra att funktionsappen misslyckas när den distribueras. För att åtgärda detta kan du ange vilken version av SDK som ska användas i global.json.

    1. dotnet --list-sdks Kör kommandot och notera den förhandsversion som du använder för närvarande under den lokala utvecklingen.
    2. dotnet new globaljson --sdk-version <SDK_VERSION> --force Kör kommandot, där <SDK_VERSION> är den version som du använder lokalt. Gör till exempel dotnet new globaljson --sdk-version dotnet-sdk-8.0.100-preview.7.23376.3 --force att systemet använder .NET 8 Preview 7 SDK när du skapar projektet.

Kommentar

På grund av just-in-time-inläsning av förhandsversionsramverk kan funktionsappar som körs i Windows uppleva ökade kalla starttider jämfört med tidigare GA-versioner.

Nästa steg