Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Wichtig
Die Unterstützung für das In-Process-Modell endet am 10. November 2026. Es wird dringend empfohlen, Ihre Apps zum isolierten Workermodell zu migrieren, um den vollständigen Support zu ermöglichen.
Dieser Artikel enthält eine Einführung in die Entwicklung von Azure Functions mithilfe von C# in .NET Klassenbibliotheken. Diese Klassenbibliotheken werden zur In-Process-Ausführung mit der Functions-Laufzeitumgebung verwendet. Ihre .NET Funktionen können alternativ _isolated über die Funktionen runtime ausführen, die mehrere Vorteile bieten. Weitere Informationen finden Sie im isolierten Workermodell. Einen umfassenden Vergleich zwischen diesen beiden Modellen finden Sie unter Unterschiede zwischen dem isolierten Workermodell und dem In-Process-Modell.
Wichtig
Dieser Artikel unterstützt .NET Klassenbibliotheksfunktionen, die mit der Laufzeit ausgeführt werden. Ihre C#-Funktionen können auch außerhalb des Prozesses ausgeführt und von der Functions-Runtime isoliert werden. Das Isolierte Arbeitsprozessmodell ist die einzige Möglichkeit, nicht LTS-Versionen von .NET und .NET Framework-Apps in aktuellen Versionen der Funktionslaufzeit auszuführen. Weitere Informationen finden Sie unter .NET isolierten Arbeitsprozessfunktionen. Einen umfassenden Vergleich zwischen isoliertem Arbeitsprozess und In-Process-.NET-Funktionen finden Sie unter Differences between in-process and isolate worker process .NET Azure Functions.
Als C#-Entwickler können Sie auch an einem der folgenden Artikel interessiert sein:
| Erste Schritte | Konzepte | Geführte Tutorials/Beispiele |
|---|---|---|
Azure Functions unterstützt C#- und C#-Skriptprogrammiersprachen. Wenn Sie Anleitungen zur
Unterstützte Versionen
Versionen der Funktionslaufzeit unterstützen bestimmte Versionen von .NET. Weitere Informationen zu Funktionsversionen finden Sie unter Azure Functions Laufzeitversionen – Übersicht. 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.
Die folgende Tabelle zeigt die höchste Ebene von .NET oder .NET Framework, die mit einer bestimmten Version von Funktionen verwendet werden kann.
| Version der Functions-Laufzeit | Isoliertes Workermodell | In-Process-Modell4 |
|---|---|---|
| Functions 4.x1 | .NET 105 .NET 9.0 .NET 8.0 .NET Framework 4.82 |
.NET 8.0 |
| Functions 1.x3 | – | .NET Framework 4.8 |
1 .NET 6 wurde zuvor auf beiden Modellen unterstützt, erreichte jedoch das Ende des offiziellen Supports am 12. November 2024. .NET 7 wurde zuvor auf dem isolierten Arbeitsmodell unterstützt, erreichte aber am 14. Mai 2024 das Ende des offiziellen Supports.
2 Der Buildvorgang erfordert auch das .NET SDK.
3 Der Support endet für Version 1.x der Azure Functions Laufzeit 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.
4 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.
5 Sie können nicht .NET 10 Apps unter Linux im Verbrauchsplan ausführen. Um unter Linux auszuführen, sollten Sie stattdessen den Flex-Verbrauchsplan verwenden. Schritt-für-Schritt-Migrationsanweisungen finden Sie unter Migrieren von Verbrauchsplan-Apps zum Flex-Verbrauchsplan.
Für die neuesten Nachrichten zu Azure Functions-Versionen, einschließlich der Entfernung bestimmter älterer Nebenversionen, beobachten Sie die Azure App Service Ankündigungen.
Aktualisieren auf Ziel-.NET 8
Apps, die das In-Process-Modell verwenden, können auf .NET 8 abzielen, indem Sie die in diesem Abschnitt beschriebenen Schritte ausführen. Wenn Sie sich jedoch für diese Option entscheiden, sollten Sie dennoch mit der Planung Ihrer Migration zum isolierten Workermodell beginnen, bevor die Unterstützung für das In-Process-Modell am 10. November 2026 endet.
Viele Apps können die Konfiguration der Funktions-App in Azure ohne Aktualisierungen an Code oder erneute Bereitstellung ändern. Um .NET 8 mit dem In-Process-Modell auszuführen, sind drei Konfigurationen erforderlich:
- Die Anwendungseinstellung
FUNCTIONS_WORKER_RUNTIMEmuss mit dem Wert „dotnet“ festgelegt werden. - Die Anwendungseinstellung
FUNCTIONS_EXTENSION_VERSIONmuss mit dem Wert „~4“ festgelegt werden. - Die Anwendungseinstellung
FUNCTIONS_INPROC_NET8_ENABLEDmuss mit dem Wert „1“ festgelegt werden. - Sie müssen die Stapelkonfiguration aktualisieren, um auf .NET 8 zu verweisen.
Die Unterstützung für .NET 8 verwendet weiterhin Version 4.x der Funktionslaufzeit, und es ist keine Änderung an der konfigurierten Laufzeitversion erforderlich.
Um Ihr lokales Projekt zu aktualisieren, stellen Sie zunächst sicher, dass Sie die neuesten Versionen lokaler Tools verwenden. Stellen Sie dann sicher, dass das Projekt auf version 4.4.0 oder höher von Microsoft.NET verweist. Sdk.Functions. Anschließend können Sie TargetFramework in „net8.0“ ändern. Sie müssen zudem local.settings.json aktualisieren, um den auf „dotnet“ festgelegten FUNCTIONS_WORKER_RUNTIME-Wert und den auf „1“ festgelegten FUNCTIONS_INPROC_NET8_ENABLED-Wert aufzunehmen.
Das folgende Beispiel ist eine minimale project Datei mit diesen Änderungen:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.4.0" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>
Das folgende Beispiel ist eine minimale local.settings.json Datei mit diesen Änderungen:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_INPROC_NET8_ENABLED": "1",
"FUNCTIONS_WORKER_RUNTIME": "dotnet"
}
}
Wenn Ihre App Microsoft.Azure.DurableTask.Netherite.AzureFunctions verwendet, stellen Sie sicher, dass sie auf Version 1.5.3 oder höher ausgerichtet ist. Aufgrund einer Verhaltensänderung in .NET 8 lösen Apps mit älteren Versionen des Pakets eine mehrdeutige Konstruktor-Ausnahme aus.
Möglicherweise müssen Sie andere Änderungen an Ihrer App basierend auf der Versionsunterstützung ihrer anderen Abhängigkeiten vornehmen.
Version 4.x der Funktionen-Laufzeit bietet gleichwertige Funktionen für .NET 6 und .NET 8. Das In-Process-Modell enthält keine anderen Features oder Updates, die in neue .NET 8-Funktionen integriert werden. Die Laufzeit unterstützt z. B. keine Schlüsseldienste. Um die neuesten .NET 8 Funktionen und Verbesserungen nutzen zu können, müssen Sie migration in das isolierte Arbeitsmodell durchführen.
Funktionsklassenbibliotheks-Projekt
In Visual Studio erstellt die Projektvorlage Azure Functions ein C#-Klassenbibliotheksprojekt, das die folgenden Dateien enthält:
- host.json – speichert Konfigurationseinstellungen, die sich auf alle Funktionen im Projekt auswirken, wenn sie lokal oder in Azure ausgeführt werden.
- local.settings.json: Speichert App-Einstellungen und Verbindungszeichenfolgen, die verwendet werden, wenn das Projekt lokal ausgeführt wird. Diese Datei enthält Geheimdaten und wird in Azure nicht in Ihrer Funktions-App veröffentlicht. Gehen Sie stattdessen so vor, dass Sie Ihrer Funktions-App App-Einstellungen hinzufügen.
Wenn Sie das Projekt erstellen, wird im Buildausgabeverzeichnis eine Ordnerstruktur generiert, die weitgehend so aussieht wie das folgende Beispiel:
<framework.version>
| - bin
| - MyFirstFunction
| | - function.json
| - MySecondFunction
| | - function.json
| - host.json
Dieses Verzeichnis wird in Azure für Ihre Funktions-App bereitgestellt. Die in Version 2.x der Functions-Runtime erforderlichen Bindungserweiterungen werden dem Projekt als NuGet-Pakete hinzugefügt.
Wichtig
Im Buildprozess wird für jede Funktion eine Datei vom Typ function.json erstellt. Diese function.json Datei soll nicht direkt bearbeitet werden. Sie können weder die Bindungskonfiguration ändern noch die Funktion deaktivieren, indem Sie diese Datei bearbeiten. Informationen zum Deaktivieren einer Funktion finden Sie unter Gewusst wie: Deaktivieren von Funktionen.
Methoden, die als Funktionen erkannt werden
In einer Klassenbibliothek ist eine Funktion eine Methode mit einem FunctionName und einem Trigger-Attribut, wie im folgenden Beispiel gezeigt:
public static class SimpleExample
{
[FunctionName("QueueTrigger")]
public static void Run(
[QueueTrigger("myqueue-items")] string myQueueItem,
ILogger log)
{
log.LogInformation($"C# function processed: {myQueueItem}");
}
}
Das Attribut FunctionName 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. Project Vorlagen erstellen häufig eine Methode namens Run, aber der Methodenname kann ein beliebiger gültiger C#-Methodenname sein. Das vorangehende Beispiel zeigt eine statische Methode, die verwendet wird, funktionen müssen jedoch nicht statisch sein.
Das Trigger-Attribut gibt den Triggertyp an und bindet die Eingabedaten an einen Methodenparameter. Die Beispielfunktion wird durch eine Warteschlangennachricht ausgelöst, und die Warteschlangennachricht wird im myQueueItem-Parameter an die Methode übergeben.
Methodensignaturparameter
Die Methodensignatur enthält möglicherweise andere Parameter als die, die mit dem Trigger-Attribut verwendet werden. Hier sind einige weitere Parameter aufgeführt, die Sie verwenden können:
- Eingabe- und Ausgabebindungen, die als solche gekennzeichnet werden, indem Sie sie mit Attributen versehen.
- Ein
ILogger- oderTraceWriter-Parameter (nur Version 1.x) für die Protokollierung. - Ein
CancellationToken-Parameter für ordnungsgemäßes Herunterfahren. - Binden von Ausdrücken Parameter zum Abrufen von Metadaten für Trigger.
Die Reihenfolge der Parameter in der Funktionssignatur spielt keine Rolle. Beispielsweise können Sie Triggerparameter für Bindungen voran- oder nachstellen und den Parameter „logger“ vor oder nach Trigger- oder Bindungsparametern anordnen.
Ausgabebindungen
Eine Funktion kann über keine Ausgabebindung oder mehrere Ausgabebindungen verfügen. Dies wird mithilfe von Ausgabeparametern definiert.
Im folgenden Beispiel wird das vorhergehende Beispiel geändert, indem eine Ausgabe-Warteschlangenbindung mit dem Namen myQueueItemCopy hinzugefügt wird. Die Funktion schreibt den Inhalt der Meldung, die die Funktion auslöst, in eine neue Warteschlangenmeldung in einer anderen Warteschlange.
public static class SimpleExampleWithOutput
{
[FunctionName("CopyQueueMessage")]
public static void Run(
[QueueTrigger("myqueue-items-source")] string myQueueItem,
[Queue("myqueue-items-destination")] out string myQueueItemCopy,
ILogger log)
{
log.LogInformation($"CopyQueueMessage function processed: {myQueueItem}");
myQueueItemCopy = myQueueItem;
}
}
Werte, die Ausgabebindungen zugewiesen sind, werden geschrieben, wenn die Funktion vorhanden ist. Sie können mehrere Ausgabebindungen in einer Funktion verwenden, indem Sie mehreren Ausgabeparametern Werte zuweisen.
In den Artikeln zu den Bindungsverweisen (z. B. Speicherwarteschlangen) wird erläutert, welche Parametertypen Sie mit Trigger-, Eingabe- oder Ausgabebindungsattributen verwenden können.
Beispiel für Bindungsausdrücke
Mit dem folgenden Code wird der Name der zu überwachenden Warteschlange für eine App-Einstellung abgerufen, und der Erstellungszeitpunkt der Warteschlangennachricht ist im Parameter insertionTime enthalten.
public static class BindingExpressionsExample
{
[FunctionName("LogQueueMessage")]
public static void Run(
[QueueTrigger("%queueappsetting%")] string myQueueItem,
DateTimeOffset insertionTime,
ILogger log)
{
log.LogInformation($"Message content: {myQueueItem}");
log.LogInformation($"Created at: {insertionTime}");
}
}
Automatisch generierte function.json-Datei
Im Buildprozess wird eine function.json-Datei in einem Funktionsordner im Ordner für Builds erstellt. Wie bereits erwähnt ist diese Datei nicht für die direkte Bearbeitung vorgesehen. Sie können weder die Bindungskonfiguration ändern noch die Funktion deaktivieren, indem Sie diese Datei bearbeiten.
Der Zweck dieser Datei besteht darin, Informationen für den Skalierungscontroller bereitzustellen, die dieser für Skalierungsentscheidungen hinsichtlich des Verbrauchsplans verwenden kann. Aus diesem Grund weist die Datei nur Triggerinformationen und keine Eingabe-/Ausgabebindungen auf.
Die generierte function.jsondatei enthält eine configurationSource-Eigenschaft, die die Laufzeit angibt, .NET Attribute für Bindungen anstelle function.jsonkonfiguration zu verwenden. Hier sehen Sie ein Beispiel:
{
"generatedBy": "Microsoft.NET.Sdk.Functions-1.0.0.0",
"configurationSource": "attributes",
"bindings": [
{
"type": "queueTrigger",
"queueName": "%input-queue-name%",
"name": "myQueueItem"
}
],
"disabled": false,
"scriptFile": "..\\bin\\FunctionApp1.dll",
"entryPoint": "FunctionApp1.QueueTrigger.Run"
}
Microsoft.NET. Sdk.Functions
Die function.json-Dateigenerierung wird durch das NuGet-Paket Microsoft.NET.Sdk.Functions ausgeführt.
Das folgende Beispiel zeigt die relevanten Teile der .csproj Dateien, die über unterschiedliche Zielframeworks in desselben Sdk Paketen verfügen:
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.5.0" />
</ItemGroup>
Wichtig
Ab Version 4.0.6517 der Kerntools müssen In-Process-Modellprojekte auf version 4.5.0 oder höher von Microsoft.NET.Sdk.Functions verweisen. Bei Verwendung einer älteren Version tritt bei dem Befehl func start ein Fehler auf.
Unter den Sdk-Paketabhängigkeiten befinden sich Auslöser und Bindungen. Ein 1.x-Projekt bezieht sich auf 1.x-Trigger und -Bindungen, da diese Trigger und Bindungen auf das .NET Framework ausgerichtet sind, während 4.x-Trigger und -Bindungen .NET Core-Ziel sind.
Das Sdk-Paket hängt außerdem von Newtonsoft.Json und indirekt von WindowsAzure.Storage ab. Diese Abhängigkeiten stellen sicher, dass Ihr Projekt die Versionen dieser Pakete verwendet, die mit der Functions-Runtime-Version funktionieren, auf die das Projekt ausgelegt ist. Beispielsweise verfügt Newtonsoft.Json über Version 11 für .NET Framework 4.6.1, die Funktionenlaufzeit, die auf .NET Framework 4.6.1 abzielt, ist jedoch nur mit Newtonsoft.Json 9.0.1 kompatibel. Daher muss Ihr Funktionscode in diesem Projekt auch Newtonsoft.Json 9.0.1 verwenden.
Der Quellcode für Microsoft.NET.Sdk.Functions ist im GitHub Repository azure-functions-vs-build-sdk verfügbar.
Lokale Runtimeversion
Visual Studio verwendet die Azure Functions Core Tools zum Ausführen von Funktionenprojekten auf dem lokalen Computer. Core Tools ist eine Befehlszeilenschnittstelle für die Functions-Runtime.
Wenn Sie die Core Tools mithilfe des Windows Installer-Pakets (MSI) oder mithilfe von npm installieren, wirkt sich dies nicht auf die core Tools-Version aus, die von Visual Studio verwendet wird. Für die Funktionen-Laufzeitversion 1.x speichert Visual Studio Core Tools-Versionen in %USERPROFILE%\AppData\Local\Azure. Functions.Cli und verwendet die neueste dort gespeicherte Version. Für Funktionen 4.x sind die Kern-Tools in der Erweiterung Azure Functions und Web Jobs Tools enthalten. Sie können für Functions 1.x anzeigen, welche Version in der Konsolenausgabe verwendet wird, wenn Sie ein Functions-Projekt ausführen:
[3/1/2018 9:59:53 AM] Starting Host (HostId=contoso2-1518597420, Version=2.0.11353.0, ProcessId=22020, Debug=False, Attempt=0, FunctionsExtensionVersion=)
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 eines Kaltstarts bei Ausführung in einem Verbrauchstarif reduzieren kann.
ReadyToRun ist in .NET 6 und höheren Versionen verfügbar und erfordert version 4.0 der Azure Functions Runtime.
Um Ihr Projekt als „ReadyToRun“ zu kompilieren, aktualisieren Sie die Projektdatei, indem Sie die Elemente <PublishReadyToRun> und <RuntimeIdentifier> hinzufügen. Das folgende Beispiel ist die Konfiguration für das Veröffentlichen in einer 32-Bit-Windows-Function-App.
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<PublishReadyToRun>true</PublishReadyToRun>
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
</PropertyGroup>
Wichtig
Ab .NET 6 wurde die Unterstützung für die Kompilierung "Composite ReadyToRun" hinzugefügt. Sehen Sie sich die plattform- und architekturübergreifenden Einschränkungen für ReadyToRun an.
Sie können Ihre App mit ReadyToRun auch über die Befehlszeile erstellen. Weitere Informationen finden Sie unter der Option -p:PublishReadyToRun=true in dotnet publish.
Unterstützte Typen für Bindungen
Jede Bindung hat ihre eigenen unterstützten Typen. Beispielsweise kann ein Blobtriggerattribut auf einen Zeichenfolgeparameter, einen POCO-Parameter, einen CloudBlockBlob-Parameter oder einen von mehreren anderen unterstützten Typen angewendet werden. Im Bindungsreferenzartikel für Blobbindungen sind alle unterstützten Parametertypen aufgelistet. Weitere Informationen hierzu finden Sie unter Trigger und Bindungen und in den Bindungsreferenzdokumenten für jeden Bindungstyp.
Tipp
Wenn Sie die HTTP- oder WebHook-Bindungen verwenden möchten, vermeiden Sie die Portauslastung, die durch nicht ordnungsgemäße Instanziierung von HttpClient verursacht werden kann. Weitere Informationen finden Sie unter How to manage connections in Azure Functions.
Binden an den Rückgabewert einer Methode
Sie können einen Rückgabewert einer Methode für eine Ausgabebindung nutzen, indem Sie das Attribut auf den Rückgabewert einer Methode anwenden. Beispiele finden Sie unter Konzepte für Azure Functions-Trigger und -Bindungen.
Verwenden Sie den Rückgabewert nur dann, wenn eine erfolgreiche Ausführung der Funktion immer einen Rückgabewert ergibt, der an die Ausgabebindung übergeben werden soll. Verwenden Sie andernfalls, wie im folgenden Abschnitt gezeigt, ICollector oder IAsyncCollector.
Schreiben von mehreren Ausgabewerten
Verwenden Sie zum Schreiben mehrerer Werte in eine Ausgabebindung oder wenn ein erfolgreicher Funktionsaufruf möglicherweise keinen Wert für die Ausgabebindung liefert, die Typen ICollector oder IAsyncCollector. Diese Typen stellen lesegeschützte Sammlungen dar, die nach Durchführung der Methode in die Ausgabebindung geschrieben werden.
In diesem Beispiel werden mehrere Warteschlangennachrichten mit ICollector in die gleiche Warteschlange geschrieben:
public static class ICollectorExample
{
[FunctionName("CopyQueueMessageICollector")]
public static void Run(
[QueueTrigger("myqueue-items-source-3")] string myQueueItem,
[Queue("myqueue-items-destination")] ICollector<string> myDestinationQueue,
ILogger log)
{
log.LogInformation($"C# function processed: {myQueueItem}");
myDestinationQueue.Add($"Copy 1: {myQueueItem}");
myDestinationQueue.Add($"Copy 2: {myQueueItem}");
}
}
Asynchron
Um eine Funktion asynchron auszuführen, verwenden Sie das async-Schlüsselwort, und geben Sie ein Task-Objekt zurück.
public static class AsyncExample
{
[FunctionName("BlobCopy")]
public static async Task RunAsync(
[BlobTrigger("sample-images/{blobName}")] Stream blobInput,
[Blob("sample-images-copies/{blobName}", FileAccess.Write)] Stream blobOutput,
CancellationToken token,
ILogger log)
{
log.LogInformation($"BlobCopy function processed.");
await blobInput.CopyToAsync(blobOutput, 4096, token);
}
}
Sie können keine out-Parameter in asynchronen Funktionen verwenden. Für Ausgabebindungen verwenden Sie stattdessen Funktionsrückgabewert oder Sammlerobjekt.
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.
Betrachten Sie den Fall, dass Sie eine Funktion verwenden, die Nachrichten in Batches verarbeitet. Die folgende Azure Service Bus ausgelöste Funktion verarbeitet ein Array von ServiceBusReceivedMessage-Objekten, die einen Batch eingehender Nachrichten darstellen, die von einem bestimmten Funktionsaufruf verarbeitet werden sollen:
using Azure.Messaging.ServiceBus;
using System.Threading;
namespace ServiceBusCancellationToken
{
public static class servicebus
{
[FunctionName("servicebus")]
public static void Run([ServiceBusTrigger("csharpguitar", Connection = "SB_CONN")]
ServiceBusReceivedMessage[] messages, CancellationToken cancellationToken, ILogger log)
{
try
{
foreach (var message in messages)
{
if (cancellationToken.IsCancellationRequested)
{
log.LogInformation("A cancellation token was received. Taking precautionary actions.");
//Take precautions like noting how far along you are with processing the batch
log.LogInformation("Precautionary activities --complete--.");
break;
}
else
{
//business logic as usual
log.LogInformation($"Message: {message} was processed.");
}
}
}
catch (Exception ex)
{
log.LogInformation($"Something unexpected happened: {ex.Message}");
}
}
}
}
Protokollierung
In Ihrem Funktionscode können Sie die Ausgabe in Protokolle schreiben, die in Application Insights als Ablaufverfolgungen angezeigt werden. Die empfohlene Vorgehensweise zum Schreiben in die Protokolle besteht darin, einen Parameter vom Typ ILogger hinzuzufügen, der in der Regel log heißt. In Version 1.x der Functions-Runtime wurde TraceWriter verwendet. Dadurch wurde ebenfalls in Application Insights geschrieben, aber es wurde keine strukturierte Protokollierung unterstützt. Verwenden Sie nicht Console.Write zum Schreiben der Protokolle, da diese Daten von Application Insights nicht aufgezeichnet werden.
ILogger
Fügen Sie in Ihrer Funktionsdefinition den Parameter ILogger ein, der strukturierte Protokollierung unterstützt.
Mit einem ILogger-Objekt rufen Sie Log<level>-Erweiterungsmethoden in ILogger auf, um Protokolle zu erstellen. Mit dem folgenden Code werden Protokolle vom Typ Information mit der Kategorie Function.<YOUR_FUNCTION_NAME>.User. geschrieben.
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, ILogger logger)
{
logger.LogInformation("Request for item with key={itemKey}.", id);
Weitere Informationen zur Implementierung von ILogger in Functions finden Sie unter Sammeln von Telemetriedaten. Bei Kategorien mit dem Präfix Function wird angenommen, dass Sie eine ILogger-Instanz verwenden. Wenn Sie sich stattdessen dafür entscheiden, einen ILogger<T> zu verwenden, könnte der Kategoriename möglicherweise auf T basieren.
Strukturierte Protokollierung
Die Reihenfolge der Platzhalter, nicht der Namen, bestimmt, welche Parameter in der Protokollnachricht verwendet werden. Angenommen, Sie verwenden den folgenden Code:
string partitionKey = "partitionKey";
string rowKey = "rowKey";
logger.LogInformation("partitionKey={partitionKey}, rowKey={rowKey}", partitionKey, rowKey);
Wenn Sie die gleiche Nachrichtenzeichenfolge beibehalten und die Reihenfolge der Parameter umkehren, befinden sich die Werte im resultierenden Nachrichtentext an den falschen Stellen.
Platzhalter werden auf diese Weise verarbeitet, damit Sie die strukturierte Protokollierung durchführen können. Application Insights speichert die Name/Wert-Paare für Parameter und die Nachrichtenzeichenfolge. Das Ergebnis ist, dass die Nachrichtenargumente zu Feldern werden, anhand denen Sie Abfragen durchführen können.
Wenn Ihr Methodenaufruf für die Protokollierung wie im vorherigen Beispiel aussieht, können Sie das Feld customDimensions.prop__rowKey abfragen. Durch das Hinzufügen des Präfix prop__ soll sichergestellt werden, dass es zwischen den Feldern, die von der Runtime hinzugefügt werden, und Feldern, die von Ihrem Funktionscode hinzugefügt werden, nicht zu Konflikten kommt.
Sie können auch die ursprüngliche Nachrichtenzeichenfolge abfragen, indem Sie auf das Feld customDimensions.prop__{OriginalFormat} verweisen.
Hier ist eine JSON-Beispieldarstellung von customDimensions-Daten angegeben:
{
"customDimensions": {
"prop__{OriginalFormat}":"C# Queue trigger function processed: {message}",
"Category":"Function",
"LogLevel":"Information",
"prop__message":"c9519cbf-b1e6-4b9b-bf24-cb7d10b1bb89"
}
}
Protokollieren benutzerdefinierter Telemetriedaten
Wichtig
OpenTelemetry wird für C#-In-Process-Funktions-Apps nicht unterstützt. Verwenden Sie für das isolierte Arbeitsmodell stattdessen den OpenTelemetry-Exporter , der als empfohlener Ansatz für benutzerdefinierte Telemetrie dient. Das klassische Application Insights SDK, das in diesem Abschnitt gezeigt wird, ist legacy und erhält keine neuen Featureupdates.
Es gibt eine funktionsspezifische Version des Application Insights SDK, mit der Sie benutzerdefinierte Telemetriedaten aus Ihren Funktionen an Application Insights senden können: Microsoft.Azure. WebJobs.Logging.ApplicationInsights. Verwenden Sie den folgenden Befehl in der Eingabeaufforderung, um das folgende Paket zu installieren:
dotnet add package Microsoft.Azure.WebJobs.Logging.ApplicationInsights --version <VERSION>
Ersetzen Sie in diesem Befehl <VERSION> durch eine Version dieses Pakets, die Ihre installierte Version von Microsoft.Azure unterstützt. WebJobs.
Im folgenden C#-Beispiel wird die benutzerdefinierte Telemetrie-API verwendet. Das Beispiel ist für eine .NET Klassenbibliothek vorgesehen, der Application Insights-Code ist jedoch für C#-Skript identisch.
Die Runtime ab Version 2.x verwendet neuere Features in Application Insights, um die Telemetrie automatisch mit dem aktuellen Vorgang zu korrelieren. Es ist nicht erforderlich, für den Vorgang die Felder Id, ParentId oder Name festzulegen.
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
using System.Linq;
namespace functionapp0915
{
public class HttpTrigger2
{
private readonly TelemetryClient telemetryClient;
/// Using dependency injection will guarantee that you use the same configuration for telemetry collected automatically and manually.
public HttpTrigger2(TelemetryConfiguration telemetryConfiguration)
{
this.telemetryClient = new TelemetryClient(telemetryConfiguration);
}
[FunctionName("HttpTrigger2")]
public Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)]
HttpRequest req, ExecutionContext context, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
DateTime start = DateTime.UtcNow;
// Parse query parameter
string name = req.Query
.FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
.Value;
// Write an event to the customEvents table.
var evt = new EventTelemetry("Function called");
evt.Context.User.Id = name;
this.telemetryClient.TrackEvent(evt);
// Generate a custom metric, in this case let's use ContentLength.
this.telemetryClient.GetMetric("contentLength").TrackValue(req.ContentLength);
// Log a custom dependency in the dependencies table.
var dependency = new DependencyTelemetry
{
Name = "GET api/planets/1/",
Target = "swapi.co",
Data = "https://swapi.co/api/planets/1/",
Timestamp = start,
Duration = DateTime.UtcNow - start,
Success = true
};
dependency.Context.User.Id = name;
this.telemetryClient.TrackDependency(dependency);
return Task.FromResult<IActionResult>(new OkResult());
}
}
}
In diesem Beispiel werden die benutzerdefinierten Metrikdaten vom Host aggregiert, bevor sie an die Tabelle „customMetrics“ gesendet werden. Weitere Informationen finden Sie in der Dokumentation zu GetMetric in Application Insights.
Bei der lokalen Ausführung müssen Sie die Einstellung APPINSIGHTS_INSTRUMENTATIONKEY mit dem Application Insights-Schlüssel zur Datei local.settings.json hinzufügen.
Rufen Sie TrackRequest oder StartOperation<RequestTelemetry> nicht an, weil doppelte Anfragen für einen Funktionsaufruf angezeigt werden. Mit der Functions-Laufzeit werden Anforderungen automatisch nachverfolgt.
Legen Sie nicht telemetryClient.Context.Operation.Id fest. Diese globale Einstellung führt zu falschen Korrelationen, wenn viele Funktionen gleichzeitig ausgeführt werden. Erstellen Sie stattdessen eine neue Telemetrieinstanz (DependencyTelemetry, EventTelemetry), und ändern Sie die Context-Eigenschaft. Übergeben Sie in der Telemetrie-Instanz dann die entsprechende Track-Methode TelemetryClient (TrackDependency(), TrackEvent(), TrackMetric()). Durch diese Methode wird sichergestellt, dass die Telemetrie die richtigen Korrelationsdetails für den aktuellen Funktionsaufruf enthält.
Testen von Funktionen
In den folgenden Artikeln wird gezeigt, wie Sie eine In-Process-C#-Klassenbibliotheksfunktion zu Testzwecken lokal ausführen:
Umgebungsvariablen
Verwenden Sie System.Environment.GetEnvironmentVariablezum Abrufen einer Umgebungsvariablen oder zum Abrufen des Werts einer App-Einstellung, wie im folgenden Codebeispiel zu sehen:
public static class EnvironmentVariablesExample
{
[FunctionName("GetEnvironmentVariables")]
public static void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log)
{
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
log.LogInformation(GetEnvironmentVariable("AzureWebJobsStorage"));
log.LogInformation(GetEnvironmentVariable("WEBSITE_SITE_NAME"));
}
private static string GetEnvironmentVariable(string name)
{
return name + ": " +
System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
}
}
App-Einstellungen können sowohl bei der lokalen Entwicklung als auch bei der Ausführung in Azure aus Umgebungsvariablen gelesen werden. Beim lokalen Entwickeln kommen App-Einstellungen aus der Values-Sammlung in der Datei local.settings.json. In beiden Umgebungen, lokal und Azure, ruft GetEnvironmentVariable("<app setting name>") den Wert der benannten App-Einstellung ab. Bei der lokalen Ausführung würde beispielsweise „My Site Name“ zurückgegeben, wenn Ihre local.settings.json-Datei { "Values": { "WEBSITE_SITE_NAME": "My Site Name" } } enthält.
Die Eigenschaft System.Configuration.ConfigurationManager.AppSettings ist eine alternative API zum Abrufen von Werten einer App-Einstellung, jedoch wird die hier gezeigte Verwendung von GetEnvironmentVariable empfohlen.
Binden zur Laufzeit
In C# und anderen .NET Sprachen können Sie ein imperative Bindungsmuster verwenden, im Gegensatz zu den declarativeBindungen in Attributen. Imperative Bindung eignet sich, wenn Bindungsparameter zur Laufzeit statt zur Entwurfszeit berechnet werden müssen. Mit diesem Muster ist die Bindung an unterstützte Eingabe- und Ausgabebindungen direkt im Funktionscode möglich.
Definieren Sie eine imperative Bindung wie folgt:
Schließen Sie für die gewünschten imperativen Bindungen kein Attribut in die Funktionssignatur ein.
Übergeben Sie einen Eingabeparameter
Binder binderoderIBinder binder.Verwenden Sie das folgende C#-Muster, um die Datenbindung auszuführen.
using (var output = await binder.BindAsync<T>(new BindingTypeAttribute(...))) { ... }BindingTypeAttributeist das attribut .NET, das Ihre Bindung definiert, undTist ein Eingabe- oder Ausgabetyp, der von diesem Bindungstyp unterstützt wird.Tdarf keinout-Parametertyp sein (wie etwaout JObject). Die Tabellenausgabebindung für mobile Apps unterstützt z. B. sechs Ausgabetypen. Sie können jedoch nur ICollector<T> oder IAsyncCollector<T> mit imperativer Bindung verwenden.
Beispiel mit einem einzigen Attribut
Mit dem folgenden Beispielcode wird eine ausgehende Speicherblob-Bindung mit einem Blobpfad erstellt, der zur Laufzeit definiert wird. Dann wird eine Zeichenfolge in das Blob geschrieben.
public static class IBinderExample
{
[FunctionName("CreateBlobUsingBinder")]
public static void Run(
[QueueTrigger("myqueue-items-source-4")] string myQueueItem,
IBinder binder,
ILogger log)
{
log.LogInformation($"CreateBlobUsingBinder function processed: {myQueueItem}");
using (var writer = binder.Bind<TextWriter>(new BlobAttribute(
$"samples-output/{myQueueItem}", FileAccess.Write)))
{
writer.Write("Hello World!");
};
}
}
BlobAttribute definiert die Storage-Blob-Eingabe- oder -Ausgabebindung, und TextWriter ist ein unterstützter Ausgabebindungstyp.
Beispiel für mehrere Attribute
Im vorherigen Beispiel wird die App-Einstellung für die Verbindungszeichenfolge des Hauptspeicherkontos der Funktions-App (AzureWebJobsStorage) abgerufen. Sie können eine benutzerdefinierte App-Einstellung angeben, die für das Speicherkonto verwendet werden soll, indem Sie das StorageAccountAttribute hinzufügen und das Attributarray an BindAsync<T>() übergeben. Verwenden Sie einen Binder-Parameter, nicht IBinder. Beispiel:
public static class IBinderExampleMultipleAttributes
{
[FunctionName("CreateBlobInDifferentStorageAccount")]
public async static Task RunAsync(
[QueueTrigger("myqueue-items-source-binder2")] string myQueueItem,
Binder binder,
ILogger log)
{
log.LogInformation($"CreateBlobInDifferentStorageAccount function processed: {myQueueItem}");
var attributes = new Attribute[]
{
new BlobAttribute($"samples-output/{myQueueItem}", FileAccess.Write),
new StorageAccountAttribute("MyStorageAccount")
};
using (var writer = await binder.BindAsync<TextWriter>(attributes))
{
await writer.WriteAsync("Hello World!!");
}
}
}
Trigger und Bindungen
Diese Tabelle zeigt die Bindungen, die in den Hauptversionen der Azure Functions Laufzeit unterstützt werden:
| type | 4.x1 | 1.x2 | Auslöser | Eingabe | Output |
|---|---|---|---|---|---|
| Blob Storage | ✔ | ✔ | ✔ | ✔ | ✔ |
| Azure Cosmos DB | ✔ | ✔ | ✔ | ✔ | ✔ |
| Azure Data Explorer | ✔ | ✔ | ✔ | ||
| Azure SQL | ✔ | ✔ | ✔ | ✔ | |
| Dapr4 | ✔ | ✔ | ✔ | ✔ | |
| Ereignisraster | ✔ | ✔ | ✔ | ✔ | |
| Event Hubs | ✔ | ✔ | ✔ | ✔ | |
| HTTP und Webhooks | ✔ | ✔ | ✔ | ✔ | |
| IoT Hub | ✔ | ✔ | ✔ | ||
| Kafka3 | ✔ | ✔ | ✔ | ||
| Mobile Apps | ✔ | ✔ | ✔ | ||
| Modellkontextprotokoll | ✔ | ✔ | |||
| Benachrichtigungs-Hubs | ✔ | ✔ | |||
| Queuespeicher | ✔ | ✔ | ✔ | ✔ | |
| Redis | ✔ | ✔ | ✔ | ✔ | |
| RabbitMQ3 | ✔ | ✔ | ✔ | ||
| SendGrid | ✔ | ✔ | ✔ | ||
| Service Bus | ✔ | ✔ | ✔ | ✔ | |
| Azure SignalR Service | ✔ | ✔ | ✔ | ✔ | |
| Tabellenspeicher | ✔ | ✔ | ✔ | ✔ | |
| Zeitgeber | ✔ | ✔ | ✔ | ||
| Twilio | ✔ | ✔ | ✔ |
- Registrieren Sie alle Bindungen außer HTTP und Timer. Siehe Registrieren Azure Functions Bindungs-Erweiterungen. Dieser Schritt ist bei Verwendung von Version 1.x der Funktionslaufzeit nicht erforderlich.
- Support endet für Version 1.x der Azure Functions Laufzeit am 14. September 2026. Migrieren Sie Ihre Apps zur Version 4.x , um den vollständigen Support zu ermöglichen.
- Trigger werden im Plan „Verbrauch“ nicht unterstützt. Für diesen Bindungstyp sind laufzeitgesteuerte Trigger erforderlich.
- Dieser Bindungstyp wird nur in Kubernetes, Azure IoT Edge und anderen selbst gehosteten Modi unterstützt.