Leitfaden zum Ausführen von Azure Functions (C#) in einem isolierten Workermodell
Dieser Artikel enthält eine Einführung in die Arbeit mit Azure Functions in .NET mithilfe des isolierten Workermodells. Mit diesem Modell kann Ihr Projekt unabhängig von anderen Runtimekomponenten auf Versionen von .NET ausgerichtet werden. Informationen zu bestimmten unterstützten .NET-Versionen finden Sie unter Unterstützte Versionen.
Über die folgenden Links können Sie sofort mit der Erstellung von .NET-Funktionen in isolierten Workermodellen beginnen.
Erste Schritte | Konzepte | Beispiele |
---|---|---|
Informationen zum Bereitstellen eines Projekts mit isoliertem Workermodell in Azure finden Sie unter Bereitstellen in Azure Functions.
Vorteile des isolierten Workermodells
Es gibt zwei Modi, in denen Sie die .NET-Klassenbibliotheksfunktionen ausführen können: entweder im gleichen Prozess wie die Functions-Hostruntime (In-Process) oder in einem isolierten Workerprozess. Die Ausführung von .NET-Funktionen in einem isolierten Workerprozess bietet folgende Vorteile:
- Weniger Konflikte: Da Ihre Funktionen in einem separaten Prozess ausgeführt werden, geraten die Assemblys Ihrer App nicht mit unterschiedlichen Versionen der gleichen Assemblys in Konflikt, die vom Hostprozess verwendet werden.
- Vollständige Kontrolle über den Prozess: Sie steuern den Start der App, können also die verwendeten Konfigurationen und die gestartete Middleware verwalten.
- Standardmäßige Abhängigkeitsinjektion: Da Sie die vollständige Kontrolle über den Prozess haben, können Sie aktuelle .NET-Verhaltensweisen für die Abhängigkeitsinjektion und die Einbindung von Middleware in Ihre Funktions-App nutzen.
- .NET-Versionsflexibilität: Dank der Ausführung außerhalb des Hostprozesses können Ihre Funktionen in .NET-Versionen ausgeführt werden, die nicht nativ von der Functions-Runtime unterstützt werden. Dies schließt auch .NET Framework ein.
Wenn Sie bereits über eine C#-Funktions-App mit In-Process-Ausführung verfügen, müssen Sie Ihre App migrieren, um diese Vorteile nutzen zu können. Weitere Informationen finden Sie unter Migrieren von .NET-Apps vom In-Process-Modell zum isolierten Workermodell.
Einen umfassenden Vergleich zwischen den beiden Modellen finden Sie unter Unterschiede zwischen einem In-Process- und einem isolierten Workerprozess in .NET-Azure Functions.
Unterstützte Versionen
Versionen der Functions-Laufzeit unterstützen bestimmte Versionen von .NET. Weitere Informationen zu den Functions-Versionen finden Sie unter Übersicht über die Runtimeversionen von Azure Functions. Die Versionsunterstützung hängt auch davon ab, ob Ihre Funktionen prozessintern oder in einem isolierten Workerprozess ausgeführt werden.
Hinweis
Informationen zum Ändern der von Ihrer Funktions-App verwendeten Functions-Runtimeversion finden Sie unter Anzeigen und Aktualisieren der aktuellen Runtimeversion.
In der folgenden Tabelle sind die höchsten .NET- bzw. .NET Framework-Versionen aufgeführt, die mit einer bestimmten Version von Functions verwendet werden können.
Version der Functions-Laufzeit | Isoliertes Workermodell | Prozessinternes Modell5 |
---|---|---|
Functions 4.x1 | .NET 9.0 (Vorschauversion) .NET 8.0 .NET 6.02 .NET Framework 4.83 |
.NET 8.0 .NET 6.02 |
Functions 1.x4 | – | .NET Framework 4.8 |
1 .NET 7 wurde zuvor beim isolierten Workermodell unterstützt, hat aber am 14. Mai 2024 das Ende der offiziellen Unterstützung erreicht.
2 .NET 6 wird ab dem 12. November 2024 nicht mehr offiziell unterstützt.
3 Für den Buildprozess ist auch das .NET SDK erforderlich.
4 Der Support für die Version 1.x der Azure Functions-Runtime endet am 14. September 2026. Weitere Informationen finden Sie in dieser Supportankündigung. Um weiterhin uneingeschränkten Support zu erhalten, müssen Sie Ihre Apps zur Version 4.x migrieren.
5 Die Unterstützung für das In-Process-Modell endet am 10. November 2026. Weitere Informationen finden Sie in dieser Supportankündigung. Um weiterhin uneingeschränkten Support zu erhalten, müssen Sie Ihre Apps zum Modell mit isolierten Workern migrieren.
Aktuelle Informationen zu Azure Functions-Releases (einschließlich Informationen zur Entfernung bestimmter älterer Nebenversionen) finden Sie unter Azure App Service-Ankündigungen.
Projektstruktur
Ein .NET-Projekt für Azure Functions mit dem isolierten Workermodell ist im Grunde ein Projekt für eine .NET-Konsolen-App mit einer unterstützten .NET-Runtime als Ziel. Die folgenden Dateien werden in jedem isolierten .NET-Projekt benötigt:
- C#-Projektdatei (.csproj), definiert das Projekt und die Abhängigkeiten
- Program.cs, der Einstiegspunkt für die App
- Alle Codedateien, die Ihre Funktionen definieren.
- Die Datei host.json, die die Konfiguration definiert, die von Funktionen in Ihrem Projekt gemeinsam genutzt wird.
- Die Datei local.settings.json, die Umgebungsvariablen definiert, die von Ihrem Projekt verwendet werden, wenn es lokal auf Ihrem Computer ausgeführt werden.
Vollständige Beispiele finden Sie im Beispielprojekt für .NET 8 sowie im Beispielprojekt für .NET Framework 4.8.
Paketverweise
Ein .NET-Projekt für Azure Functions mit dem isolierten Workermodell verwendet individuelle Pakete für Kernfunktionen und Bindungserweiterungen.
Erforderliche Pakete
Die folgenden Pakete werden benötigt, damit Ihre .NET-Funktionen in einem isolierten Workerprozess ausgeführt werden können:
Version 2.x (Vorschau)
In Version 2.x der Kernpakete wurden die unterstützten Frameworks geändert. Außerdem bieten sie Unterstützung für neue .NET-APIs aus diesen späteren Versionen. Wenn Sie .NET 9 (Vorschau) oder höher verwenden, muss Ihre App bei beiden Paketen auf Version 2.0.0-preview1 oder höher verweisen.
Die ersten Vorschauversionen sind mit Code kompatibel, der für Version 1.x geschrieben wurde. Während des Vorschauzeitraums führen neuere Versionen jedoch möglicherweise Verhaltensänderungen ein, die den von Ihnen geschriebenen Code beeinflussen können.
Beachten Sie beim Aktualisieren auf die 2.x-Versionen die folgenden Änderungen:
- Ab Version 2.0.0-preview2 fügt Microsoft.Azure.Functions.Worker.Sdk Standardkonfigurationen für SDK-Containerbuilds hinzu.
- Ab Version 2.0.0-preview2 von Microsoft.Azure.Functions.Worker:
- Diese Version bietet Unterstützung für
IHostApplicationBuilder
. Einige Beispiele in diesem Leitfaden enthalten Registerkarten mit Alternativen, dieIHostApplicationBuilder
verwenden. Für diese Beispiele sind 2.x-Versionen erforderlich. - Die Gültigkeitsprüfung des Dienstanbieterbereichs ist standardmäßig enthalten, wenn die Ausführung in einer Entwicklungsumgebung erfolgt. Dieses Verhalten entspricht dem von ASP.NET Core.
- Die
EnableUserCodeException
-Option ist standardmäßig aktiviert. Die Eigenschaft ist jetzt als veraltet markiert. - Die
IncludeEmptyEntriesInMessagePayload
-Option ist standardmäßig aktiviert. Wenn diese Option aktiviert ist, löst sie Nutzdaten aus, die Sammlungen mit stets leeren Einträge darstellen. Wenn beispielsweise eine Nachricht ohne Text gesendet wird, ist für die Triggerdaten trotzdem ein leererstring[]
enthalten. Der Einschluss leerer Einträge vereinfacht Querverweise mit Metadatenarrays, auf die die Funktion ebenfalls verweisen kann. Sie können dieses Verhalten deaktivieren, indem Sie in derWorkerOptions
-DienstkonfigurationIncludeEmptyEntriesInMessagePayload
auffalse
festlegen. - Die
ILoggerExtensions
-Klasse wurde inFunctionsLoggerExtensions
umbenannt. Die Umbenennung verhindert einen Fehler durch einen mehrdeutigen Aufruf bei Verwendung vonLogMetric()
in einerILogger
-Instanz.
- Diese Version bietet Unterstützung für
Erweiterungspakete
Da .NET-Funktionen in einem isolierten Workerprozess andere Bindungstypen verwenden, benötigen sie spezifische Pakete mit Bindungserweiterungen.
Diese Erweiterungspakete finden Sie unter Microsoft.Azure.Functions.Worker.Extensions.
Start und Konfiguration
Wenn Sie das isolierte Workermodell verwenden, haben Sie Zugriff auf die Startfunktion Ihrer Funktions-App, die sich in der Regel in Program.cs
befindet. Sie sind dafür verantwortlich, eine eigene Hostinstanz zu erstellen und zu starten. Sie haben daher auch direkten Zugriff auf die Konfigurationspipeline für Ihre App. Mit .NET-Funktionen in einem isolierten Workerprozess können Sie viel einfacher Konfigurationen und Abhängigkeiten hinzufügen sowie Ihre eigene Middleware ausführen.
Im Folgenden sehen Sie ein Beispiel für eine 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();
Für diesen Code ist using Microsoft.Extensions.DependencyInjection;
erforderlich.
Bevor Sie Build()
für IHostBuilder
aufrufen, sollten Sie:
- Entweder
ConfigureFunctionsWebApplication()
aufrufen, wenn Sie ASP.NET Core-Integration verwenden, oder andernfallsConfigureFunctionsWorkerDefaults()
. Einzelheiten zu diesen Optionen finden Sie unter HTTP-Trigger.
Wenn Sie Ihre Anwendung mit F# schreiben, benötigen einige Trigger- und Bindungserweiterungen eine zusätzliche Konfiguration. Lesen Sie die Setupdokumentation für die Blobs-Erweiterung, die Tables-Erweiterung und die Cosmos DB-Erweiterung, wenn Sie diese Erweiterungen in einer F#-App verwenden möchten. - Konfigurieren Sie Dienste oder App-Konfigurationen, die für Ihr Projekt erforderlich sind. Ausführliche Informationen finden Sie unter Konfiguration.
Wenn Sie die Verwendung von Application Insights planen, müssen SieAddApplicationInsightsTelemetryWorkerService()
undConfigureFunctionsApplicationInsights()
im DelegatenConfigureServices()
aufrufen. Weitere Informationen finden Sie unter Application Insights.
Wenn Ihr Projekt auf .NET Framework 4.8 ausgerichtet ist, müssen Sie auch FunctionsDebugger.Enable();
hinzufügen, bevor Sie den HostBuilder erstellen. Es sollte die erste Zeile Ihrer Main()
-Methode sein. Weitere Informationen finden Sie unter Debuggen für .NET Framework.
Der HostBuilder wird zur Erstellung und Rückgabe einer vollständig initialisierten IHost
-Instanz verwendet. Diese führen Sie asynchron aus, um Ihre Funktions-App zu starten.
await host.RunAsync();
Konfiguration
Der Typ des verwendeten Generators bestimmt, wie Sie die Anwendung konfigurieren können.
Die ConfigureFunctionsWorkerDefaults-Methode dient dazu, die für die Ausführung der Funktions-App erforderlichen Einstellungen hinzuzufügen. Die Methode enthält die folgenden Funktionen:
- Standardsatz von Konvertern.
- Legen Sie die Standard-JsonSerializerOptions fest, um die Groß- und Kleinschreibung von Eigenschaftsnamen zu übergehen.
- Integration in Azure Functions-Protokollierung.
- Ausgabe verbindlicher Middleware und Funktionen.
- Middleware für die Funktionsausführung.
- Standardmäßige gRPC-Unterstützung.
.ConfigureFunctionsWorkerDefaults()
Da Sie Zugriff auf die HostBuilder-Pipeline haben, können Sie auch App-spezifische Konfigurationen während der Initialisierung festlegen. Zum Hinzufügen der Konfigurationsquellen, die für Ihren Code erforderlich sind, können Sie die ConfigureAppConfiguration-Methode (auch mehrmals) für HostBuilder aufrufen. Weitere Informationen zur App-Konfiguration finden Sie unter Konfiguration in ASP.NET Core.
Diese Konfigurationen gelten nur für den Workercode, den Sie erstellen. Sie beeinflussen nicht direkt die Konfiguration des Functions-Hosts oder der Trigger und Bindungen. Wenn Sie Änderungen am Funktionshost oder -trigger und an der Bindungskonfiguration vornehmen möchten, müssen Sie weiterhin die Datei host.json verwenden.
Hinweis
Benutzerdefinierte Konfigurationsquellen können nicht für die Konfiguration von Auslösern und Bindungen verwendet werden. Die Auslöser- und Bindungskonfiguration muss für die Funktionenplattform und nicht nur für Ihren Anwendungscode verfügbar sein. Sie können diese Konfiguration über die Anwendungseinstellungen, Key Vault-Verweise oder App Configuration-Verweise bereitstellen.
Abhängigkeitsinjektion
Beim isolierte Workermodell werden standardmäßige .NET-Mechanismen zum Einfügen von Diensten verwendet.
Wenn Sie einen HostBuilder
verwenden, rufen Sie ConfigureServices im Host-Generator auf und verwenden die Erweiterungsmethoden in IServiceCollection, um bestimmte Dienste einzufügen. Im folgenden Beispiel wird eine Dependency Injection für einen Singletondienst durchgeführt:
.ConfigureServices(services =>
{
services.AddSingleton<IHttpResponderService, DefaultHttpResponderService>();
})
Für diesen Code ist using Microsoft.Extensions.DependencyInjection;
erforderlich. Weitere Informationen finden Sie unter Dependency Injection in ASP.NET Core.
Registrieren von Azure-Clients
Die Abhängigkeitsinjektion kann für die Interaktion mit anderen Azure-Diensten verwendet werden. Sie können Clients aus dem Azure SDK für .NET mithilfe des Pakets Microsoft.Extensions.Azure einfügen. Nach der Installation des Pakets registrieren Sie die Clients, indem Sie AddAzureClients()
für die Dienstsammlung in Program.cs
aufrufen. Im folgenden Beispiel wird ein benannter Client für Azure-Blobs konfiguriert:
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();
Das folgende Beispiel zeigt, wie wir diese Registrierung und SDK-Typen verwenden können, um Blobinhalte mithilfe eines eingefügten Clients als Stream aus einem Container in einen anderen zu kopieren:
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!");
}
}
}
ILogger<T>
in diesem Beispiel wurde ebenfalls durch Abhängigkeitsinjektion abgerufen und somit automatisch registriert. Weitere Informationen zu den Konfigurationsoptionen für die Protokollierung finden Sie unter Protokollierung.
Tipp
Im Beispiel wurde eine Literalzeichenfolge für den Namen des Clients in Program.cs
und der Funktion verwendet. Erwägen Sie stattdessen die Verwendung einer gemeinsamen konstanten Zeichenfolge, die für die Funktionsklasse definiert ist. Sie können z. B. beiden Speicherorten public const string CopyStorageClientName = nameof(_copyContainerClient);
hinzufügen und dann an beiden Speicherorten auf BlobCopier.CopyStorageClientName
verweisen. In ähnlicher Weise können Sie den Namen des Konfigurationsabschnitts mit der Funktion statt in Program.cs
definieren.
Middleware
Das isolierte Workermodell unterstützt auch die Middleware-Registrierung mit einem Modell, das dem in ASP.NET vorhandenen Modell ähnelt. Dieses Modell bietet Ihnen die Möglichkeit, Logik in die Aufrufpipeline einzufügen, und vorher und nachher Funktionen auszuführen.
Die Erweiterungsmethode ConfigureFunctionsWorkerDefaults weist eine Überladung auf, mit der Sie Ihre eigene Middleware registrieren können, wie im folgenden Beispiel zu sehen ist.
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();
Die Erweiterungsmethode UseWhen
kann verwendet werden, um bedingt ausgeführte Middleware zu registrieren. An diese Methode muss ein Prädikat übergeben werden, das einen booleschen Wert zurückgibt, und die Middleware nimmt an der Aufrufverarbeitungspipeline teil, wenn der Rückgabewert des Prädikats true
ist.
Die folgenden Erweiterungsmethoden für FunctionContext erleichtern das Arbeiten mit Middleware im isolierten Modell.
Methode | BESCHREIBUNG |
---|---|
GetHttpRequestDataAsync |
Ruft die HttpRequestData -Instanz ab, wenn der Aufruf durch einen HTTP-Trigger erfolgt. Diese Methode gibt eine Instanz von ValueTask<HttpRequestData?> zurück, die nützlich ist, wenn Sie Nachrichtendaten lesen möchten, z. B. Anforderungsheader und Cookies. |
GetHttpResponseData |
Ruft die HttpResponseData -Instanz ab, wenn der Aufruf durch einen HTTP-Trigger erfolgt. |
GetInvocationResult |
Ruft eine Instanz von InvocationResult ab, die das Ergebnis der aktuellen Funktionsausführung darstellt. Verwenden Sie die Value -Eigenschaft, um den Wert nach Bedarf abzurufen oder festzulegen. |
GetOutputBindings |
Ruft die Ausgabebindungseinträge für die aktuelle Funktionsausführung ab. Jeder Eintrag im Ergebnis dieser Methode ist vom Typ OutputBindingData . Sie können die Value -Eigenschaft verwenden, um den Wert nach Bedarf abzurufen oder festzulegen. |
BindInputAsync |
Bindet ein Eingabebindungselement für die angeforderte BindingMetadata -Instanz. Sie können diese Methode beispielsweise verwenden, wenn Sie über eine Funktion mit einer BlobInput -Eingabebindung verfügen, die von Ihrer Middleware verwendet werden muss. |
Hier sehen Sie ein Beispiel für eine Middlewareimplementierung, die die Instanz HttpRequestData
liest und die Instanz HttpResponseData
während der Funktionsausführung aktualisiert:
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);
}
}
Diese Middleware überprüft, ob ein bestimmter Anforderungsheader (x-correlationId) vorhanden ist. Wenn dies der Fall ist, verwendet sie den Headerwert, um einen Antwortheader zu stempeln. Andernfalls generiert sie einen neuen GUID-Wert und verwendet diesen zum Stempeln des Antwortheaders. Ein ausführlicheres Beispiel für die Verwendung von benutzerdefinierter Middleware in ihrer Funktions-APP finden Sie im Beispiel für eine benutzerdefinierte Middleware-Referenz.
Anpassen der JSON-Serialisierung
Das isolierte Arbeitsmodell verwendet System.Text.Json
standardmäßig. Sie können das Verhalten des Serialisierungsmoduls anpassen, indem Sie Dienste als Teil Ihrer Program.cs
Datei konfigurieren. In diesem Abschnitt wird die allgemeine Serialisierung behandelt, die keinen Einfluss auf die HTTP-Trigger JSON-Serialisierung mit ASP.NET Core-Integration hat, die separat konfiguriert werden muss.
Das folgende Beispiel zeigt diese Verwendung ConfigureFunctionsWebApplication
, funktioniert aber auch 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();
Sie können stattdessen JSON.NET (Newtonsoft.Json
) für die Serialisierung verwenden. Dazu installieren Sie das Microsoft.Azure.Core.NewtonsoftJson
Paket. Anschließend würden Sie in Ihrer Dienstregistrierung die Serializer
Eigenschaft für die WorkerOptions
Konfiguration neu zuweisen. Das folgende Beispiel zeigt diese Verwendung ConfigureFunctionsWebApplication
, funktioniert aber auch 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();
Methoden, die als Funktionen erkannt werden
Eine Funktionsmethode ist eine öffentliche Methode einer öffentlichen Klasse mit einem Function
-Attribut, das auf die Methode angewendet wird, und einem Trigger-Attribut, das auf einen Ausgabeparameter angewendet wird. Dies wird im folgenden Beispiel veranschaulicht:
[Function(nameof(QueueFunction))]
[QueueOutput("output-queue")]
public string[] Run([QueueTrigger("input-queue")] Album myQueueItem, FunctionContext context)
Das Trigger-Attribut gibt den Triggertyp an und bindet die Eingabedaten an einen Methodenparameter. Die zuvor gezeigte Beispielfunktion wird durch eine Warteschlangennachricht ausgelöst, und die Warteschlangennachricht wird im Parameter myQueueItem
an die Methode übergeben.
Das Attribut Function
kennzeichnet die Methode als Funktionseinstiegspunkt. Der Name muss innerhalb eines Projekts eindeutig sein, mit einem Buchstaben beginnen und darf nur Buchstaben, Ziffern, _
und -
enthalten. Bis zu 127 Zeichen sind zulässig. Projektvorlagen erstellen oft eine Methode namens Run
, aber der Name der Methode kann ein beliebiger gültiger C#-Methodennamen sein. Die Methode muss ein öffentliches Element einer öffentlichen Klasse sein. Es sollte im Allgemeinen eine Instanzmethode sein, damit Dienste über Abhängigkeitsinjektion übergeben werden können.
Funktionsparameter
Hier sind Sie einige der Parameter, die Sie in eine Funktionsmethodensignatur einschließen können:
- Bindungen, die entsprechend gekennzeichnet werden, indem die Parameter als Attribute dargestellt werden. Die Funktion muss genau einen Triggerparameter enthalten.
- Ein Ausführungskontextobjekt, das Informationen zum aktuellen Aufruf bereitstellt.
- Ein Abbruchtoken zum ordnungsgemäßen Herunterfahren.
Ausführungskontext
Der isolierte .NET-Prozess übergibt ein FunctionContext-Objekt an Ihre Funktionsmethoden. Mit diesem Objekt erhalten Sie eine ILogger
-Instanz, um in die Protokolle zu schreiben, indem Sie die GetLogger-Methode aufrufen und eine categoryName
Zeichenfolge anbieten. Sie können diesen Kontext verwenden, um eine ILogger
-Instanz zu erhalten, ohne die Abhängigkeitsinjektion verwenden zu müssen. Weitere Informationen finden Sie unter Protokollierung.
Abbruchtoken
Eine Funktion kann einen CancellationToken-Parameter annehmen, der es dem Betriebssystem ermöglicht, den Code vor dem Beenden der Funktion zu benachrichtigen. Sie können diese Benachrichtigung verwenden, um sicherzustellen, dass die Funktion nicht auf eine Weise unerwartet beendet wird, die die Daten in einem inkonsistenten Zustand hinterlässt.
Abbruchtoken werden in .NET-Funktionen unterstützt, wenn sie in einem isolierten Workerprozess ausgeführt werden. Im folgenden Beispiel wird eine Ausnahme ausgelöst, wenn eine Abbruchanforderung empfangen wird:
[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);
}
}
Im folgenden Beispiel werden Bereinigungsaktionen ausgeführt, wenn eine Abbruchanforderung empfangen wird:
[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);
}
}
Bindungen
Bindungen werden mithilfe von Attributen in Methoden, Parametern und Rückgabetypen definiert. Bindungen können Daten in Form von Zeichenfolgen, Arrays und serialisierbare Typen, beispielsweise Plain Old CLR Objects (POCOs) bieten. Bei einigen Bindungserweiterungen können Sie auch eine Bindung an dienstspezifische Typen vornehmen, die in Dienst-SDKs definiert sind.
Informationen zu HTTP-Triggern finden Sie im Abschnitt HTTP-Trigger.
Umfassende Referenzbeispiele zur Verwendung von Triggern und Bindungen mit Funktionen in isolierten Workerprozessen finden Sie im Referenzbeispiel für Bindungserweiterungen.
Eingabebindungen
Eine Funktion kann über null oder mehr Eingabebindungen verfügen, die Daten an eine andere Funktion übergeben können. Genau wie Trigger werden Eingabebindungen definiert, indem ein Bindungsattribut auf einen Eingabeparameter angewendet wird. Wenn die Funktion ausgeführt wird, versucht die Runtime, die in der Bindung angegebenen Daten abzurufen. Die angeforderten Daten sind häufig von den Informationen abhängig, die vom Triggern mithilfe von Bindungsparametern bereitgestellt werden.
Ausgabebindungen
Wenn Sie eine Ausgabebindung schreiben möchten, müssen Sie ein Ausgabebindungsattribut an die Funktionsmethode anfügen. Dadurch wird definiert, wie in den gebundenen Dienst geschrieben werden soll. Der von der Methode zurückgegebene Wert wird in die Ausgabebindung geschrieben. Im folgenden Beispiel wird ein Zeichenfolgenwert mithilfe einer Ausgabebindung in die Nachrichtenwarteschlange output-queue
geschrieben:
[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;
}
Mehrere Ausgabebindungen
Die Daten, die in eine Ausgabebindung geschrieben werden, sind immer der Rückgabewert der Funktion. Wenn Sie in mehr als eine Ausgabebindung schreiben müssen, müssen Sie einen benutzerdefinierten Rückgabetyp erstellen. Bei diesem Rückgabetyp muss das Ausgabebindungsattribut auf eine oder mehrere Eigenschaften der Klasse angewendet werden. Das folgende Beispiel ist eine HTTP-ausgelöste Funktion mit ASP.NET Core-Integration, die sowohl in die HTTP-Antwort als auch auf eine Warteschlangenausgabebindung schreibt:
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; }
}
}
Wenn Sie benutzerdefinierte Rückgabetypen für mehrere Ausgabebindungen mit ASP.NET Core-Integration verwenden, müssen Sie der Eigenschaft, die das Ergebnis bereitstellt, das [HttpResult]
Attribut hinzufügen. Das HttpResult
-Attribut ist verfügbar, wenn Sie SDK 1.17.3-preview2 oder höher mit der HTTP-Erweiterung, Version 3.2.0 oder höher, und der ASP.NET Core-Erweiterung, Version 1.3.0 oder höher verwenden.
SDK-Typen
Bei einigen dienstspezifischen Bindungstypen können Bindungsdaten mithilfe von Typen aus Dienst-SDKs und Frameworks bereitgestellt werden. Sie bieten zusätzliche Funktionen, die über das hinausgehen, was eine serialisierte Zeichenfolge oder ein POCO-Objekt (Plain Old CLR Object) bieten kann. Damit die neueren Typen genutzt werden können, muss Ihr Projekt aktualisiert werden, um neuere Versionen von Kernabhängigkeiten zu verwenden.
Abhängigkeit | Versionsanforderung |
---|---|
Microsoft.Azure.Functions.Worker | 1.18.0 oder höher |
Microsoft.Azure.Functions.Worker.Sdk | 1.13.0 oder höher |
Wenn Sie SDK-Typen lokal auf Ihrem Computer testen, müssen Sie auch Azure Functions Core Tools (ab Version 4.0.5000) verwenden. Sie können Ihre aktuelle Version mithilfe des Befehls func version
überprüfen.
Für jede Trigger- und Bindungserweiterung gilt zusätzlich eine gesonderte Anforderung an die Mindestversion, wie in den Referenzartikeln zur jeweiligen Erweiterung beschrieben. Folgende dienstspezifische Bindungen bieten SDK-Typen:
Dienst | Trigger | Eingabebindung | Ausgabebindung |
---|---|---|---|
Azure-Blobs | Allgemein verfügbar | Allgemein verfügbar | SDK-Typen nicht empfohlen1 |
Azure-Warteschlangen | Allgemein verfügbar | Keine Eingabebindung vorhanden | SDK-Typen nicht empfohlen1 |
Azure Service Bus | Allgemein verfügbar | Keine Eingabebindung vorhanden | SDK-Typen nicht empfohlen1 |
Azure Event Hubs | Allgemein verfügbar | Keine Eingabebindung vorhanden | SDK-Typen nicht empfohlen1 |
Azure Cosmos DB | Nicht verwendete SDK-Typen2 | Allgemein verfügbar | SDK-Typen nicht empfohlen1 |
Azure-Tabellen | Kein Trigger vorhanden | Allgemein verfügbar | SDK-Typen nicht empfohlen1 |
Azure Event Grid | Allgemein verfügbar | Keine Eingabebindung vorhanden | SDK-Typen nicht empfohlen1 |
1 Bei Ausgabeszenarien, in denen Sie einen SDK-Typ verwenden würden, sollten Sie SDK-Clients direkt erstellen und mit ihnen arbeiten, anstatt eine Ausgabebindung zu verwenden. Ein Beispiel für die Abhängigkeitsinjektion finden Sie unter Registrieren von Azure-Clients.
2 Der Cosmos DB-Trigger verwendet den Azure Cosmos DB-Änderungsfeed und macht Änderungsfeedelemente als von JSON serialisierbare Typen verfügbar. Für dieses Szenario ist das Fehlen von SDK-Typen beabsichtigt.
Hinweis
Bei Verwendung von Bindungsausdrücken, die auf Triggerdaten basieren, können SDK-Typen für den Trigger selbst nicht verwendet werden.
HTTP-Trigger
HTTP-Trigger ermöglichen das Aufrufen einer Funktion durch eine HTTP-Anforderung. Es gibt zwei verschiedene Ansätze, die verwendet werden können:
- Ein ASP.NET Core-Integrationsmodell, das Konzepte verwendet, die ASP.NET Core-Entwickler*innen vertraut sind
- Ein integriertes Modell, das keine zusätzlichen Abhängigkeiten erfordert und benutzerdefinierte Typen für HTTP-Anforderungen und -Antworten verwendet. Dieser Ansatz ist weiterhin verfügbar, um Abwärtskompatibilität mit früheren isolierten .NET-Worker-Apps zu gewährleisten.
ASP.NET Core-Integration
In diesem Abschnitt wird gezeigt, wie Sie mit den zugrunde liegenden HTTP-Anforderungs- und Antwortobjekten mithilfe von Typen aus ASP.NET Core wie HttpRequest, HttpResponse und IActionResult arbeiten. Dieses Modell ist für Apps, die auf .NET Framework ausgerichtet sind, nicht verfügbar. Stattdessen muss das integrierte Modell verwendet werden.
Hinweis
Nicht alle Features von ASP.NET Core werden von diesem Modell verfügbar gemacht. Insbesondere sind die ASP.NET Core-Middlewarepipeline und Routingfunktionen nicht verfügbar. Für die ASP.NET Core-Integration müssen aktualisierte Pakete verwendet werden.
So aktivieren Sie die ASP.NET Core-Integration für HTTP
Fügen Sie in Ihrem Projekt einen Verweis auf das Paket Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore (ab Version 1.0.0) hinzu.
Aktualisieren Sie Ihr Projekt so, dass die folgenden spezifischen Paketversionen verwendet werden:
- Microsoft.Azure.Functions.Worker.Sdk: Version 1.11.0. oder höher.
- Microsoft.Azure.Functions.Worker: Version 1.16.0 oder höher.
Aktualisieren Sie in Ihrer Datei
Program.cs
die Konfiguration des Host-Generators, umConfigureFunctionsWebApplication()
aufzurufen. Damit wirdConfigureFunctionsWorkerDefaults()
ersetzt, wenn Sie diese Methode anderweitig verwenden. Das folgende Beispiel zeigt ein minimales Setup ohne weitere Anpassungen:using Microsoft.Azure.Functions.Worker; using Microsoft.Extensions.Hosting; var host = new HostBuilder() .ConfigureFunctionsWebApplication() .Build(); host.Run();
Aktualisieren Sie ggf. vorhandene Funktionen mit HTTP-Trigger für die Verwendung der ASP.NET Core-Typen. Im folgenden Beispiel werden die standardmäßige HTTP-Anforderung (
HttpRequest
) sowieIActionResult
für eine einfache Funktion vom Typ „hello, world“ verwendet:[Function("HttpFunction")] public IActionResult Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req) { return new OkObjectResult($"Welcome to Azure Functions, {req.Query["name"]}!"); }
JSON-Serialisierung mit ASP.NET Core-Integration
ASP.NET Core verfügt über eine eigene Serialisierungsebene und ist nicht von Anpassung der allgemeinen Serialisierungskonfigurationbetroffen. Um das für Ihre HTTP-Trigger verwendete Serialisierungsverhalten anzupassen, müssen Sie einen .AddMvc()
-Aufruf als Teil der Dienstregistrierung einschließen. Die zurückgegebenen IMvcBuilder
können verwendet werden, um die JSON-Serialisierungseinstellungen von ASP.NET Core zu ändern. Das folgende Beispiel zeigt, wie Sie JSON.NET (Newtonsoft.Json
) für die Serialisierung mit diesem Ansatz konfigurieren:
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();
Integriertes HTTP-Modell
HTTP-Trigger übersetzen eingehende HTTP-Anforderungsnachrichten in ein HttpRequestData-Objekt, das an die Funktion übergeben wird. Dieses Objekt liefert die Anforderungsdaten wie Headers
, Cookies
, Identities
, URL
und optional eine Nachricht Body
. Dieses Objekt ist eine Darstellung der HTTP-Anforderung, aber nicht direkt mit dem zugrunde liegenden HTTP-Listener oder der empfangenen Nachricht verbunden.
Entsprechend gibt die Funktion ein HttpResponseData-Objekt zurück, das die Daten zur Erstellung der HTTP-Antwort enthält, zum Beispiel Nachricht StatusCode
, Headers
, und optional Nachricht Body
.
Das folgende Beispiel veranschaulicht die Verwendung von HttpRequestData
und 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;
}
Logging
Sie können Protokolle mithilfe einer ILogger<T>
- oder ILogger
-Instanz schreiben. Die Protokollierung kann durch Abhängigkeitsinjektion eines ILogger<T>
- oder ILoggerFactory-Elements abgerufen werden:
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}");
}
}
Die Protokollierung kann auch aus einem FunctionContext-Objekt abgerufen werden, das an Ihre Funktion übergeben wird. Rufen Sie die Methode GetLogger<T> oder die Methode GetLoggerauf, und übergeben Sie dabei einen Zeichenfolgenwert, der den Namen der Kategorie darstellt, in welche die Protokolle geschrieben werden. Die Kategorie ist normalerweise der Name der spezifischen Funktion, aus der die Protokolle geschrieben werden. Weitere Informationen zu Kategorien finden Sie im Artikel zur Überwachung.
Verwenden Sie die Methoden von ILogger<T>
und ILogger
, um verschiedene Protokolliergrade wie LogWarning
oder LogError
zu schreiben. Weitere Informationen zu den Protokolliergraden finden Sie im Artikel zur Überwachung. Sie können die Protokolliergrade für Ihrem Code hinzugefügte Komponenten anpassen, indem Sie Filter registrieren:
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();
Im Rahmen der Konfiguration Ihrer App in Program.cs
können Sie auch definieren, auf welche Weise Fehler in Ihren Protokollen vermerkt werden. Das Standardverhalten hängt vom Typ des verwendeten Generators ab.
Bei Verwendung von HostBuilder
können standardmäßig Ausnahmen, die von Ihrem Code ausgelöst werden, von RpcException
umschlossen werden. Um diese gesonderte Ebene zu entfernen, legen Sie beim Konfigurieren des Generators die EnableUserCodeException
-Eigenschaft auf „true“ fest:
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults(builder => {}, options =>
{
options.EnableUserCodeException = true;
})
.Build();
host.Run();
Application Insights
Sie können Ihre Anwendung mit isolierten Prozessen so konfigurieren, dass Protokolle direkt an Application Insights ausgegeben werden. Dieses Verhalten ersetzt das Standardverhalten der Weiterleitung benutzerdefinierter Protokolle über den Host und wird empfohlen, da Sie so die Ausgabe dieser Protokolle steuern können.
Installieren von Paketen
Um Protokolle direkt über Ihren Code in Application Insights zu schreiben, können Sie Verweise auf die folgenden Pakete in Ihrem Projekt hinzufügen:
- Microsoft.Azure.Functions.Worker.ApplicationInsights (ab Version 1.0.0)
- Microsoft.ApplicationInsights.WorkerService
Sie können die folgenden Befehle ausführen, um diese Verweise Ihrem Projekt hinzuzufügen:
dotnet add package Microsoft.ApplicationInsights.WorkerService
dotnet add package Microsoft.Azure.Functions.Worker.ApplicationInsights
Konfigurieren des Starts
Wenn die Pakete installiert sind, müssen Sie AddApplicationInsightsTelemetryWorkerService()
und ConfigureFunctionsApplicationInsights()
während der Dienstkonfiguration in der Datei Program.cs
aufrufen, wie im folgenden Beispiel gezeigt:
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();
Der Aufruf von ConfigureFunctionsApplicationInsights()
fügt ein ITelemetryModule
hinzu, das an einer von Functions definierten ActivitySource
lauscht. Dadurch werden die Abhängigkeitstelemetriedaten erstellt, die zur Unterstützung der verteilten Ablaufverfolgung erforderlich sind. Informationen zu AddApplicationInsightsTelemetryWorkerService()
und dessen Verwendung finden Sie unter Application Insights für Workerdienstanwendungen.
Verwalten von Protokollebenen
Wichtig
Der Functions-Host und der Worker des isolierten Prozesses verfügen über unterschiedliche Konfigurationen für Protokolliergrade usw. Eine Application Insights-Konfiguration in host.json wirkt sich nicht auf die Protokollierung durch den Worker aus, ebenso wirkt sich eine Konfiguration in Ihrem Workercode nicht auf die Protokollierung durch den Host aus. Wenn Ihr Szenario eine Anpassung auf beiden Ebenen erfordert, müssen Sie an beiden Stellen Änderungen vornehmen.
Der Rest der Anwendung funktioniert weiterhin mit ILogger
und ILogger<T>
. Standardmäßig fügt das Application Insights SDK jedoch einen Protokollierungsfilter hinzu, der die Protokollierung anweist, nur Warnungen und schwerwiegendere Protokolliergrade zu erfassen. Wenn Sie dieses Verhalten deaktivieren möchten, entfernen Sie die Filterregel, die zur Dienstkonfiguration gehört:
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();
Leistungsoptimierungen
In diesem Abschnitt werden Optionen beschrieben, die Sie zum Verbessern der Leistung beim Kaltstart aktivieren können.
Im Allgemeinen sollte Ihre App die neuesten Versionen ihrer Kernabhängigkeiten verwenden. Ihr Projekt sollte mindestens wie folgt aktualisiert werden:
- Führen Sie für Microsoft.Azure.Functions.Worker mindestens ein Upgrade auf die Version 1.19.0 durch.
- Führen Sie für Microsoft.Azure.Functions.Worker.Sdk mindestens ein Upgrade auf die Version 1.16.4 durch.
- Fügen Sie einen Frameworkverweis auf
Microsoft.AspNetCore.App
hinzu, es sei denn, Ihre App ist auf .NET Framework ausgerichtet.
Der folgende Codeschnipsel zeigt diese Konfiguration im Kontext einer Projektdatei:
<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>
Platzhalter
Platzhalter sind eine Plattformfunktion, die den Kaltstart für Apps verbessert, die auf .NET 6 oder auf eine höhere Version ausgerichtet sind. Um diese Optimierung verwenden zu können, müssen mithilfe der folgenden Schritte explizit Platzhalter aktiviert werden:
Aktualisieren Sie die Projektkonfiguration so, dass sie die neuesten Abhängigkeitsversionen verwendet, wie im vorherigen Abschnitt beschrieben.
Legen Sie die Anwendungseinstellung
WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED
auf1
fest. Hierzu können Sie den folgenden Befehl vom Typ az functionapp config appsettings set verwenden:az functionapp config appsettings set -g <groupName> -n <appName> --settings 'WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED=1'
Ersetzen Sie in diesem Beispiel
<groupName>
durch den Namen der Ressourcengruppe und<appName>
durch den Namen Ihrer Funktions-App.Achten Sie darauf, dass die Eigenschaft
netFrameworkVersion
der Funktions-App dem Zielframework Ihres Projekts entspricht (.NET 6 oder höher). Hierzu können Sie den folgenden Befehl vom Typ az functionapp config set verwenden:az functionapp config set -g <groupName> -n <appName> --net-framework-version <framework>
Ersetzen Sie in diesem Beispiel auch
<framework>
durch die entsprechende Versionszeichenfolge für Ihre .NET-Zielversion (beispielsweisev8.0
).Stellen Sie sicher, dass Ihre Funktions-App für die Verwendung eines 64-Bit-Prozesses konfiguriert ist. Hierzu können Sie den folgenden Befehl vom Typ az functionapp config set verwenden:
az functionapp config set -g <groupName> -n <appName> --use-32bit-worker-process false
Wichtig
Wenn Sie WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED
auf 1
festlegen, müssen alle anderen Funktions-App-Konfigurationen ordnungsgemäß festgelegt werden. Andernfalls kann die Funktions-App möglicherweise nicht gestartet werden.
Optimierter Executor
Der Funktions-Executor ist eine Komponente der Plattform, die die Ausführung von Aufrufen auslöst. Ab der Version 1.16.2 des SDK ist standardmäßig eine optimierte Version dieser Komponente aktiviert. Es ist keine weitere Konfiguration erforderlich.
ReadyToRun
Sie können ihre Funktions-App als ReadyToRun-Binärdateien kompilieren. ReadyToRun ist eine Form der Vorabkompilierung, die zur Optimierung der Startleistung beitragen und die Auswirkungen von Kaltstarts bei Ausführung in einem Verbrauchstarif reduzieren kann. ReadyToRun ist in .NET 6 und höher verfügbar und setzt mindestens Version 4.0 der Azure Functions-Runtime voraus.
ReadyToRun erfordert, dass Sie das Projekt für die Runtimearchitektur der Hosting-App erstellen. Wenn diese nicht aufeinander abgestimmt sind, tritt bei der App beim Start ein Fehler auf. Wählen Sie Ihren Runtimebezeichner aus der folgenden Tabelle aus:
Betriebssystem | Die App ist 32-Bi1 | Runtimebezeichner |
---|---|---|
Windows | True | win-x86 |
Windows | False | win-x64 |
Linux | True | N/V (nicht unterstützt) |
Linux | False | linux-x64 |
1 Einige andere Leistungsoptimierungen sind 64-Bit-Apps vorbehalten.
Um zu überprüfen, ob Ihre Windows-App eine 32-Bit- oder 64-Bit-App ist, können Sie den folgenden CLI-Befehl ausführen. Ersetzen Sie dabei <group_name>
durch den Namen Ihrer Ressourcengruppe und <app_name>
durch den Namen Ihrer Anwendung. Die Ausgabe „true“ gibt an, dass die App eine 32-Bit-App ist, und „false“ gibt an, dass es sich um eine 64-Bit-App handelt.
az functionapp config show -g <group_name> -n <app_name> --query "use32BitWorkerProcess"
Sie können Ihre Anwendung mit dem folgenden Befehl mit den gleichen Ersetzungen in 64-Bit ändern:
az functionapp config set -g <group_name> -n <app_name> --use-32bit-worker-process false`
Um Ihr Projekt als „ReadyToRun“ zu kompilieren, aktualisieren Sie die Projektdatei, indem Sie die Elemente <PublishReadyToRun>
und <RuntimeIdentifier>
hinzufügen. Das folgende Beispiel zeigt eine Konfiguration für die Veröffentlichung in einer Windows-64-Bit-Funktions-App.
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>
Wenn Sie den Runtimebezeichner (<RuntimeIdentifier>
) nicht als Teil der Projektdatei festlegen möchten, können Sie ihn auch als Teil des Veröffentlichungsvorgangs selbst konfigurieren. Bei einer Windows 64-Bit-Funktions-App lautet der .NET-CLI-Befehl beispielsweise wie folgt:
dotnet publish --runtime win-x64
In Visual Studio muss die Option Zielruntime im Veröffentlichungsprofil auf den korrekten Runtimebezeichner festgelegt werden. Bei Verwendung des Standardwerts Portierbar wird ReadyToRun nicht verwendet.
Bereitstellen in Azure Functions
Bei Ausführung Ihres Funktionscodeprojekt in Azure muss es entweder in einer Funktions-App oder in einem Linux-Container ausgeführt werden. Die Funktions-App und andere erforderliche Azure-Ressourcen müssen vorhanden sein, bevor Sie Ihren Code bereitstellen.
Sie können Ihre Funktions-App auch in einem Linux-Container bereitstellen. Weitere Informationen finden Sie unter Arbeiten mit Containern und Azure Functions.
Erstellen von Azure-Ressourcen
Sie können Ihre Funktions-App und andere erforderliche Ressourcen in Azure mithilfe einer der folgenden Methoden erstellen:
- Visual Studio: Visual Studio kann während des Codeveröffentlichungsprozesses Ressourcen für Sie erstellen.
- Visual Studio Code: Visual Studio Code kann eine Verbindung mit Ihrem Abonnement herstellen, die von Ihrer App benötigten Ressourcen erstellen und dann Ihren Code veröffentlichen.
- Azure CLI: Sie können die Azure CLI verwenden, um die erforderlichen Ressourcen in Azure zu erstellen.
- Azure PowerShell: Sie können Azure PowerShell verwenden, um die erforderlichen Ressourcen in Azure zu erstellen.
- Bereitstellungsvorlagen: Sie können ARM-Vorlagen und Bicep-Dateien verwenden, um die Bereitstellung der erforderlichen Ressourcen in Azure zu automatisieren. Achten Sie darauf, dass Ihre Vorlage alle erforderlichen Einstellungen enthält.
- Azure-Portal: Sie können die erforderlichen Ressourcen im Azure-Portal erstellen.
Veröffentlichen der Anwendung
Nach Erstellung Ihrer Funktions-App und anderer erforderlicher Ressourcen in Azure können Sie das Codeprojekt mithilfe einer der folgenden Methoden für Azure bereitstellen:
- Visual Studio: Einfache manuelle Bereitstellung während der Entwicklung.
- Visual Studio Code: Einfache manuelle Bereitstellung während der Entwicklung.
- Azure Functions Core Tools: Bereitstellung der Projektdatei über die Befehlszeile.
- Continuous Deployment: Nützlich für die laufende Wartung, häufig in einem Stagingslot.
- Bereitstellungsvorlagen: Sie können ARM-Vorlagen oder Bicep-Dateien verwenden, um Paketbereitstellungen zu automatisieren.
Weitere Informationen finden Sie unter Bereitstellungstechnologien in Azure Functions.
Payload der Bereitstellung
Viele Bereitstellungsmethoden verwenden ein ZIP-Archiv. Wenn Sie das ZIP-Archiv selbst erstellen, muss es die in diesem Abschnitt beschriebene Struktur aufweisen. Andernfalls treten beim Starten der App möglicherweise Fehler auf.
Die Payload der Bereitstellung sollte mit der Ausgabe eines dotnet publish
-Befehls übereinstimmen, jedoch ohne den einschließenden übergeordneten Ordner. Das ZIP-Archiv sollte aus den folgenden Dateien erstellt werden:
.azurefunctions/
extensions.json
functions.metadata
host.json
worker.config.json
- Ausführbare Datei Ihres Projekts (eine Konsolen-App)
- Andere unterstützende Dateien und Verzeichnisse in Peer-Konfiguration für diese ausführbare Datei
Diese Dateien werden vom Buildprozess generiert. Sie sollten nicht direkt bearbeitet werden.
Beim Vorbereiten eines ZIP-Archivs für die Bereitstellung sollten Sie nur den Inhalt des Ausgabeverzeichnisses und nicht das einschließende Verzeichnis selbst komprimieren. Wenn das Archiv in das aktuelle Arbeitsverzeichnis extrahiert wird, müssen die oben aufgeführten Dateien sofort sichtbar sein.
Anforderungen für die Bereitstellung
Je nach Betriebssystem müssen gewisse Anforderungen erfüllt werden, um .NET-Funktionen im isolierten Workermodell in Azure ausführen zu können:
- FUNCTIONS_WORKER_RUNTIME muss auf
dotnet-isolated
festgelegt werden. - netFrameworkVersion muss auf die gewünschte Version festgelegt werden.
Wenn Sie Ihre Funktions-App in Azure mithilfe der Methoden aus dem vorherigen Abschnitt erstellen, werden diese erforderlichen Einstellungen für Sie hinzugefügt. Wenn Sie diese Ressourcen mithilfe von ARM-Vorlagen oder Bicep-Dateien für die Automatisierung erstellen, müssen Sie sie in der Vorlage festlegen.
Debuggen
Bei lokaler Ausführung mit Visual Studio oder Visual Studio Code können Sie Ihr Projekt mit isoliertem .NET-Worker wie gewohnt debuggen. Es gibt jedoch zwei Debugszenarien, die nicht wie erwartet funktionieren.
Remotedebuggen mit Visual Studio
Da Ihre App mit isoliertem Workerprozess außerhalb der Functions-Runtime ausgeführt wird, müssen Sie den Remotedebugger an einen separaten Prozess anfügen. Weitere Informationen zum Debuggen mithilfe von Visual Studio finden Sie unter Remotedebugging.
Debuggen für .NET Framework
Wenn Ihr isoliertes Projekt für .NET Framework 4.8 konzipiert ist, erfordert der aktuelle Vorschaubereich manuelle Schritte zum Aktivieren von Debuggen. Diese Schritte sind nicht erforderlich, wenn Sie ein anderes Zielframework verwenden.
Ihre App sollte mit einem Aufruf von FunctionsDebugger.Enable();
als erster Vorgang beginnen. Dieser erfolgt in der Main()
-Methode, bevor Sie einen HostBuilder initialisieren. Die Datei Program.cs
sollte in etwa wie folgt aussehen:
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();
}
}
}
Nun müssen Sie das Anfügen an den Prozess mithilfe eines .NET Framework-Debuggers manuell ausführen. Visual Studio führt diesen Schritt nicht automatisch für .NET Framework-Apps in isolierten Workerprozessen aus, und der Vorgang „Debuggen starten“ sollte vermieden werden.
Führen Sie in Ihrem Projektverzeichnis (oder dem Buildausgabeverzeichnis) Folgendes aus:
func host start --dotnet-isolated-debug
Dadurch wird Ihr Worker gestartet, und der Prozess wird mit der folgenden Meldung beendet:
Azure Functions .NET Worker (PID: <process id>) initialized in debug mode. Waiting for debugger to attach...
Dabei ist <process id>
die ID für Ihren Workerprozess. Sie können jetzt Visual Studio zum manuellen Anfügen an den Prozess verwenden. Anweisungen zu diesem Vorgang finden Sie unter Anfügen an einen ausgeführten Prozess.
Nachdem der Debugger angefügt wurde, wird die Prozessausführung fortgesetzt, und Sie können mit dem Debuggen beginnen.
.NET-Vorschauversionen
Vor einer allgemein verfügbaren Version kann eine .NET-Version mit dem Status Vorschauversion oder Go-live veröffentlicht werden. Einzelheiten zu diesen Zuständen finden Sie in der offiziellen .NET-Supportrichtlinie .
Es kann zwar möglich sein, eine bestimmte Version aus einem lokalen Functions-Projekt als Ziel zu verwenden, aber Funktions-Apps, die in Azure gehostet werden, sind möglicherweise nicht über diese Version verfügbar. Azure Functions kann nur mit Releases vom Typ „Vorschauversion“ oder „Go-live“ verwendet werden, die in diesem Abschnitt angegeben sind.
Azure Functions kann derzeit mit den folgenden Vorschau- oder Liveversionen von .NET verwendet werden:
Betriebssystem | .NET-Vorschauversion |
---|---|
Windows | .NET 9 Preview 61, 2 |
Linux | .NET 9 RC21, 3 |
1 Für die erfolgreiche Ausrichtung auf .NET 9 muss Ihr Projekt auf die 2.x-Versionen der Kernpakete verweisen. Bei Verwendung von Visual Studio ist für .NET 9 Version 17.12 oder höher erforderlich.
2 Während der Vorschau wird die Unterstützung für Windows in einigen Clients möglicherweise nicht angezeigt.
3 .NET 9 wird für die Flex-Verbrauchs-SKU noch nicht unterstützt.
Eine Liste der allgemein verfügbaren Versionen, die Sie verwenden können, finden Sie unter unterstützten Versionen .
Verwenden eines .NET-Vorschau-SDK
Um Azure Functions mit einer .NET-Vorschauversion zu verwenden, müssen Sie Ihr Projekt wie folgt aktualisieren:
- Installieren der relevanten .NET SDK-Version in Ihrer Entwicklungsumgebung
- Ändern der
TargetFramework
-Einstellung in Ihrer.csproj
-Datei
Bei der Bereitstellung in einer Funktions-App in Azure müssen Sie auch sicherstellen, dass das Framework für die App verfügbar gemacht wird. Während des Vorschauzeitraums werden die neuen Vorschauversion in einigen Tools und Umgebungen möglicherweise nicht als Option angezeigt. Wenn die im Azure-Portal enthaltene Vorschauversion nicht angezeigt wird, können Sie beispielsweise die REST-API, Bicep-Vorlagen oder die Azure-Befehlszeilenschnittstelle verwenden, um die Version manuell zu konfigurieren.
Verwenden Sie für Apps, die unter Windows gehostet werden, den folgenden Azure CLI-Befehl. Ersetzen Sie <groupName>
durch den Namen der Ressourcengruppe, und ersetzen Sie <appName>
durch den Namen Ihrer Funktions-App. Ersetzen Sie <framework>
durch die entsprechende Versionszeichenfolge (z. B. v8.0
).
az functionapp config set -g <groupName> -n <appName> --net-framework-version <framework>
Überlegungen zur Verwendung von .NET-Vorschauversionen
Berücksichtigen Sie Folgendes, wenn Sie Functions mit Vorschauversionen von .NET verwenden:
Wenn Sie Ihre Funktionen in Visual Studio erstellen, müssen Sie die Version Visual Studio Preview verwenden, die das Erstellen von Azure Functions-Projekten mit .NET-Vorschau-SDKs unterstützt.
Achten Sie darauf, dass Sie über die neuesten Functions-Tools und -Vorlagen verfügen. So aktualisieren Sie Ihre Tools
- Navigieren Sie zu Tools>Optionen, und wählen Sie unter Projekte und Projektmappen die Option Azure Functions aus.
- Wählen Sie Nach Updates suchen aus, und installieren Sie Updates, wenn Sie dazu aufgefordert werden.
Während eines Vorschauzeitraums verfügt Ihre Entwicklungsumgebung möglicherweise über eine neuere .NET-Vorschauversion als der gehostete Dienst. Dies kann dazu führen, dass Ihre Funktions-App nicht funktioniert, wenn sie bereitgestellt wird. Um dieses Problem zu beheben, können Sie in
global.json
die zu verwendende SDK-Version angeben.- Führen Sie den Befehl
dotnet --list-sdks
aus, und notieren Sie sich die Vorschauversion, die Sie derzeit bei der lokalen Entwicklung verwenden. - Führen Sie den Befehl
dotnet new globaljson --sdk-version <SDK_VERSION> --force
aus.<SDK_VERSION>
ist hierbei die lokal verwendete Version.dotnet new globaljson --sdk-version dotnet-sdk-8.0.100-preview.7.23376.3 --force
führt beispielsweise dazu, dass das System beim Erstellen Ihres Projekts das .NET 8 Preview 7 SDK verwendet.
- Führen Sie den Befehl
Hinweis
Aufgrund des Just-In-Time-Ladens von Vorschauframeworks können die Kaltstartzeiten bei Funktions-Apps, die unter Windows ausgeführt werden, im Vergleich zu früheren allgemein verfügbaren Versionen länger sein.