Dela via


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 Processmodell4
Funktioner 4.x1 .NET 9.0
.NET 8.0
.NET Framework 4.82
.NET 8.0
Funktioner 1.x3 saknas .NET Framework 4.8

1 .NET 6 hade tidigare stöd för båda modellerna men nådde slutet av det officiella stödet den 12 november 2024. .NET 7 hade tidigare stöd för den isolerade arbetsmodellen men nådde slutet av det officiella stödet den 14 maj 2024.

2 Byggprocessen kräver också .NET SDK.

3 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.

4 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:

Version 2.x

2.x-versionerna av kärnpaketen ändrar de ramverk som stöds och ger stöd för nya .NET-API:er från dessa senare versioner. När du riktar in dig på .NET 9 eller senare måste appen referera till version 2.0.0 eller senare av båda paketen.

Observera följande ändringar när du uppdaterar till 2.x-versionerna:

  • Från och med version 2.0.0 av Microsoft.Azure.Functions.Worker.Sdk:
  • Från och med version 2.0.0 av Microsoft.Azure.Functions.Worker:
    • Den här versionen lägger till stöd för IHostApplicationBuilder. Några exempel i den här guiden innehåller flikar för att visa alternativ med hjälp av IHostApplicationBuilder. De här exemplen kräver 2.x-versionerna.
    • Validering av tjänstleverantörsomfång ingår som standard om det körs i en utvecklingsmiljö. Det här beteendet matchar ASP.NET Core.
    • Alternativet EnableUserCodeException är aktiverat som standard. Egenskapen är nu markerad som föråldrad.
    • Alternativet IncludeEmptyEntriesInMessagePayload är aktiverat som standard. Med det här alternativet aktiverat kan utlösa nyttolaster som representerar samlingar alltid innehålla tomma poster. Om ett meddelande till exempel skickas utan brödtext skulle en tom post fortfarande finnas i string[] för utlösardata. Inkluderingen av tomma poster underlättar korsreferenser med metadatamatriser som funktionen också kan referera till. Du kan inaktivera det här beteendet genom att ange IncludeEmptyEntriesInMessagePayload i false tjänstkonfigurationen WorkerOptions .
    • Klassen ILoggerExtensions har bytt namn till FunctionsLoggerExtensions. Byt namn förhindrar ett tvetydigt anropsfel när du använder LogMetric() på en ILogger instans.
    • För appar som använder HttpResponseDataWriteAsJsonAsync() anger metoden inte längre statuskoden till 200 OK. I 1.x överskrörs andra felkoder som har angetts.
  • 2.x-versionerna släpper .NET 5 TFM-stöd.

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 den isolerade arbetsmodellen 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()IHostBuilderbö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

Vilken typ av byggare du använder avgör hur du kan konfigurera programmet.

Metoden ConfigureFunctionsWorkerDefaults används för att lägga till de inställningar som krävs för att funktionsappen ska köras. Metoden 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 konfigurationskällor som krävs av koden. Mer information om appkonfiguration finns i Konfiguration i ASP.NET Core.

Dessa konfigurationer gäller endast för den arbetskod som du skapar, och de påverkar inte konfigurationen av Functions-värden eller utlösare och bindningar direkt. 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

Den isolerade arbetsmodellen använder standardmekanismer för .NET för att mata in tjänster.

När du använder en HostBuilderanropar du ConfigureServices på värdverktyget och använder tilläggsmetoderna på 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.Azure.Functions.Worker;
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.DependencyInjection;
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

Den isolerade arbetsmodellen 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 . Det här avsnittet beskriver generell serialisering och påverkar inte HTTP-utlösarens JSON-serialisering med ASP.NET Core-integrering, som måste konfigureras separat.

I följande exempel visas detta med hjälp av ConfigureFunctionsWebApplication, men det fungerar också för ConfigureFunctionsWorkerDefaults:

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

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();

host.Run();

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:

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

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();

host.Run();

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}"};

    _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 är en HTTP-utlöst funktion som använder ASP.NET Core-integrering som skriver till både HTTP-svaret och en köutdatabindning:

public class MultipleOutputBindings
{
    private readonly ILogger<MultipleOutputBindings> _logger;

    public MultipleOutputBindings(ILogger<MultipleOutputBindings> logger)
    {
        _logger = logger;
    }

    [Function("MultipleOutputBindings")]
    public MyOutputType Run([HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req)
    {
        _logger.LogInformation("C# HTTP trigger function processed a request.");
        var myObject = new MyOutputType
        {
            Result = new OkObjectResult("C# HTTP trigger function processed a request."),
            MessageText = "some output"
        };
        return myObject;
    }

    public class MyOutputType
    {
        [HttpResult]
        public IActionResult Result { get; set; }

        [QueueOutput("myQueue")]
        public string MessageText { get; set; }
    }
}

När du använder anpassade returtyper för flera utdatabindningar med ASP.NET Core-integrering måste du lägga till [HttpResult] attributet i egenskapen som ger resultatet. Attributet är tillgängligt när du använder SDK 1.17.3-preview2 eller senare tillsammans med version 3.2.0 eller senare av HTTP-tillägget och version 1.3.0 eller senare av ASP.NET Core-tillägget.HttpResult

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 anropar ConfigureFunctionsWebApplication(). Detta ersätter ConfigureFunctionsWorkerDefaults() om du skulle använda den metoden annars. I följande exempel visas en minimal konfiguration utan andra anpassningar:

    using Microsoft.Azure.Functions.Worker;
    using Microsoft.Extensions.Hosting;
    
    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"]}!");
    }
    

JSON-serialisering med ASP.NET Core-integrering

ASP.NET Core har ett eget serialiseringslager och påverkas inte av att anpassa den allmänna serialiseringskonfigurationen. Om du vill anpassa serialiseringsbeteendet som används för dina HTTP-utlösare måste du inkludera ett anrop som en .AddMvc() del av tjänstregistreringen. Den returnerade IMvcBuilder kan användas för att ändra JSON-serialiseringsinställningarna för ASP.NET Core. I följande exempel visas hur du konfigurerar JSON.NET (Newtonsoft.Json) för serialisering med den här metoden:

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

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureServices(services =>
    {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
        services.AddMvc().AddNewtonsoftJson();
    })
    .Build();
host.Run();

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

Du kan 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:

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. Standardbeteendet beror på vilken typ av byggare du använder.

När du använder en HostBuilder, som standard kan undantag som genereras av koden hamna 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:

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

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

host.Run();

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. Om du inte använder .NET Aspire rekommenderar vi att du konfigurerar direkt Application Insights-integrering eftersom det ger dig kontroll över hur dessa loggar genereras.

Application Insights-integrering är inte aktiverat som standard i alla installationsfunktioner. Vissa mallar skapar Functions-projekt med nödvändiga paket och startkod som kommenteras ut. Om du vill använda Application Insights-integrering kan du avkommentera raderna i Program.cs och projektets .csproj fil. Anvisningarna i resten av det här avsnittet beskriver också hur du aktiverar integreringen.

Om projektet ingår i en .NET Aspire-orkestrering använder det OpenTelemetry för övervakning i stället. Du bör inte aktivera direkt Application Insights-integrering i .NET Aspire-projekt. Konfigurera i stället Azure Monitor OpenTelemetry-exportören som en del av standardprojektet för tjänsten. Om ditt Functions-projekt använder Application Insights-integrering i en .NET Aspire-kontext får programmet fel vid start.

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:

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

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, 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 Portal: Du kan skapa nödvändiga resurser i Azure Portal.

Publicera programmet

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.

Nyttolast för distribution

Många av distributionsmetoderna använder ett zip-arkiv. Om du skapar zip-arkivet själv måste det följa strukturen som beskrivs i det här avsnittet. Om den inte gör det kan det uppstå fel i din app vid start.

Distributionsnyttolasten bör matcha utdata från ett dotnet publish kommando, men utan den omslutande överordnade mappen. Zip-arkivet ska göras från följande filer:

  • .azurefunctions/
  • extensions.json
  • functions.metadata
  • host.json
  • worker.config.json
  • Ditt körbara projekt (en konsolapp)
  • Andra stödfiler och kataloger som är peer-kopplade till den körbara filen

Dessa filer genereras av byggprocessen och de är inte avsedda att redigeras direkt.

När du förbereder ett zip-arkiv för distribution bör du bara komprimera innehållet i utdatakatalogen, inte själva den omslutande katalogen. När arkivet extraheras till den aktuella arbetskatalogen måste filerna som anges ovan vara omedelbart synliga.

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.

.NET Aspire (förhandsversion)

.NET Aspire är en åsiktsstack som förenklar utvecklingen av distribuerade program i molnet. Du kan registrera .NET 8- och .NET 9-projekt för isolerade arbetsmodeller i Aspire 9.0-orkestreringar med hjälp av förhandsversionsstöd. I avsnittet beskrivs kärnkraven för enlistning.

Den här integreringen kräver specifik konfiguration:

  • Använd Aspire 9.0 eller senare och .NET 9 SDK. Aspire 9.0 stöder .NET 8- och .NET 9-ramverken.
  • Om du använder Visual Studio uppdaterar du till version 17.12 eller senare. Du måste också ha den senaste versionen av Functions-verktygen för Visual Studio. Om du vill söka efter uppdateringar går du till Verktygsalternativ>, väljer Azure Functions under Projekt och lösningar. Välj Sök efter uppdateringar och installera uppdateringar enligt anvisningarna.
  • I Aspire-appvärdprojektet:
    • Du måste referera till Aspire.Hosting.Azure.Functions.
    • Du måste ha en projektreferens till ditt Functions-projekt.
    • I appvärdens Program.csmåste du även inkludera projektet genom att anropa AddAzureFunctionsProject<TProject>() på din IDistributedApplicationBuilder. Den här metoden används i stället för den AddProject<TProject>() som du använder för andra projekttyper. Om du bara använder AddProject<TProject>()startar inte Functions-projektet korrekt.
  • I Functions-projektet:
    • Du måste referera till 2.x-versionerna av Microsoft.Azure.Functions.Worker och Microsoft.Azure.Functions.Worker.Sdk. Du måste också uppdatera alla referenser som du har till Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore 2.x-versionen.
    • Du Program.cs bör använda versionen IHostApplicationBuilder av start av värdinstansen.
    • Om du vill använda standardinställningarna för Aspire-tjänsten bör du inkludera en projektreferens till standardprojektet för tjänsten. Innan du skapar din IHostApplicationBuilder i Program.csbör du även inkludera ett anrop till builder.AddServiceDefaults().
    • Du bör inte behålla konfigurationen i local.settings.json, förutom inställningen FUNCTIONS_WORKER_RUNTIME , som ska förbli "dotnet-isolerad". Annan konfiguration bör anges via appvärdprojektet.
    • Du bör ta bort alla direkta Application Insights-integreringar. Övervakning i Aspire hanteras i stället via dess OpenTelemetry-stöd.

I följande exempel visas ett minimalt Program.cs för ett appvärdprojekt:

var builder = DistributedApplication.CreateBuilder(args);

builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject");

builder.Build().Run();

I följande exempel visas ett minimalt Program.cs för ett Functions-projekt som används i Aspire:

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

var builder = FunctionsApplication.CreateBuilder(args);

builder.AddServiceDefaults();

builder.ConfigureFunctionsWebApplication();

builder.Build().Run();

Detta inkluderar inte standardkonfigurationen för Application Insights som du ser i många av de andra Program.cs exemplen i den här artikeln. I stället konfigureras Aspires OpenTelemetry-integrering via anropet builder.AddServiceDefaults() .

Överväganden och metodtips för .NET Aspire-integrering

Tänk på följande när du utvärderar .NET Aspire med Azure Functions:

  • Stöd för Azure Functions med .NET Aspire finns för närvarande i förhandsversion. När du publicerar Aspire-lösningen till Azure under förhandsgranskningsperioden distribueras Functions-projekt som Azure Container Apps-resurser utan händelsedriven skalning. Azure Functions-stöd är inte tillgängligt för appar som distribueras i det här läget.
  • Konfigurationen av utlösare och bindningar via Aspire är för närvarande begränsad till specifika integreringar. Mer information finns i Anslutningskonfiguration med Aspire .
  • Du Program.cs bör använda versionen IHostApplicationBuilder av start av värdinstansen. På så sätt kan du anropa builder.AddServiceDefaults() för att lägga till .NET Aspire-tjänstens standardinställningar i ditt Functions-projekt.
  • Aspire använder OpenTelemetry för övervakning. Du kan konfigurera Aspire för att exportera telemetri till Azure Monitor via standardprojektet för tjänsten. I många andra Azure Functions-kontexter kan du inkludera direkt integrering med Application Insights genom att registrera telemetritjänsten. Detta rekommenderas inte i Aspire och kan leda till körningsfel med version 2.22.0 av Microsoft.ApplicationInsights.WorkerService. Du bör ta bort alla direkta Application Insights-integreringar från ditt Functions-projekt när du använder Aspire.
  • För Functions-projekt som har registrerats i en Aspire-orkestrering bör merparten av programkonfigurationen komma från Aspire-appvärdprojektet. Du bör vanligtvis undvika att ange saker i local.settings.json, förutom inställningen FUNCTIONS_WORKER_RUNTIME . Om samma miljövariabel anges av local.settings.json och Aspire använder systemet Aspire-versionen.
  • Konfigurera inte Lagringsemulatorn för några anslutningar i local.settings.json. Många Functions-startmallar innehåller emulatorn som standard för AzureWebJobsStorage. Emulatorkonfiguration kan dock uppmana vissa IDE:er att starta en version av emulatorn som kan vara i konflikt med den version som Aspire använder.

Anslutningskonfiguration med Aspire

Azure Functions kräver en värdlagringsanslutning (AzureWebJobsStorage) för flera av dess kärnbeteenden. När du anropar AddAzureFunctionsProject<TProject>() i appvärdprojektet skapas en standardanslutning AzureWebJobsStorage och tillhandahålls till Functions-projektet. Den här standardanslutningen använder Storage-emulatorn för lokala utvecklingskörningar och etablerar automatiskt ett lagringskonto när det distribueras. Om du vill ha ytterligare kontroll kan du ersätta den här anslutningen genom att anropa .WithHostStorage() functions-projektresursen.

I följande exempel visas ett minimalt Program.cs för ett programvärdprojekt som ersätter värdlagringen:

var builder = DistributedApplication.CreateBuilder(args);

var myHostStorage = builder.AddAzureStorage("myHostStorage");

builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
    .WithHostStorage(myHostStorage);

builder.Build().Run();

Kommentar

När Aspire etablerar värdlagringen i publiceringsläge skapar den som standard rolltilldelningar för rollen Lagringskontodeltagare, Storage Blob Data-deltagare, Lagringsködatadeltagare och Lagringstabelldatadeltagare .

Dina utlösare och bindningar refererar till anslutningar efter namn. Vissa Aspire-integreringar är aktiverade för att tillhandahålla dessa via ett anrop till WithReference() på projektresursen:

Aspire-integrering Kommentar
Azure Blobs När Aspire etablerar resursen skapar den som standard rolltilldelningar för rollrollerna Storage Blob Data Contributor, Storage Queue Data Contributor och Storage Table Data Contributor .
Azure Queues När Aspire etablerar resursen skapar den som standard rolltilldelningar för rollrollerna Storage Blob Data Contributor, Storage Queue Data Contributor och Storage Table Data Contributor .
Azure Event Hubs När Aspire etablerar resursen skapas som standard en rolltilldelning med hjälp av rollen Azure Event Hubs-dataägare .
Azure Service Bus När Aspire etablerar resursen skapas som standard en rolltilldelning med hjälp av rollen Azure Service Bus-dataägare .

I följande exempel visas ett minimalt Program.cs för ett programvärdprojekt som konfigurerar en köutlösare. I det här exemplet har motsvarande köutlösare egenskapen Connection inställd på "MyQueueTriggerConnection".

var builder = DistributedApplication.CreateBuilder(args);

var myAppStorage = builder.AddAzureStorage("myAppStorage").RunAsEmulator();
var queues = myAppStorage.AddQueues("queues");

builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
    .WithReference(queues, "MyQueueTriggerConnection");

builder.Build().Run();

För andra integreringar anropar anrop för att WithReference ställa in konfigurationen på ett annat sätt, vilket gör den tillgänglig för Aspire-klientintegreringar, men inte för utlösare och bindningar. För dessa integreringar bör du anropa WithEnvironment() för att skicka anslutningsinformationen för utlösaren eller bindningen som ska matchas. I följande exempel visas hur du anger miljövariabeln "MyBindingConnection" för en resurs som exponerar ett anslutningssträng uttryck:

builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
    .WithEnvironment("MyBindingConnection", otherIntegration.Resource.ConnectionStringExpression);

Du kan konfigurera både WithReference() och WithEnvironment() om du vill att en anslutning ska användas både av Aspire-klientintegreringar och systemet för utlösare och bindningar.

För vissa resurser kan strukturen för en anslutning skilja sig från när du kör den lokalt och när du publicerar den till Azure. I föregående exempel otherIntegration kan vara en resurs som körs som en emulator, så ConnectionStringExpression skulle returnera en emulator anslutningssträng. Men när resursen publiceras kan Aspire konfigurera en identitetsbaserad anslutning och ConnectionStringExpression returnera tjänstens URI. I det här fallet kan du behöva ange ett annat miljövariabelnamn för att konfigurera identitetsbaserade anslutningar för Azure Functions. I följande exempel används builder.ExecutionContext.IsPublishMode för att villkorligt lägga till det nödvändiga suffixet:

builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
    .WithEnvironment("MyBindingConnection" + (builder.ExecutionContext.IsPublishMode ? "__serviceUri" : ""), otherIntegration.Resource.ConnectionStringExpression);

Beroende på ditt scenario kan du också behöva justera de behörigheter som ska tilldelas för en identitetsbaserad anslutning. Du kan använda ConfigureConstruct<T>() metoden för att anpassa hur Aspire konfigurerar infrastrukturen när den publicerar projektet.

Läs referenssidorna för varje bindning för mer information om de anslutningsformat som den stöder och vilka behörigheter dessa format kräver.

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 måste du vidta manuella åtgärder 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 din funktionsapp i Azure måste du också se till att ramverket görs tillgängligt för appen. Under förhandsgranskningsperioden kanske vissa verktyg och upplevelser inte innehåller den nya förhandsversionen som ett alternativ. Om du inte ser den förhandsversion som ingår i Azure Portal kan du till exempel använda REST API, Bicep-mallar eller Azure CLI för att konfigurera versionen manuellt.

För appar som finns i Windows använder du följande Azure 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