Tworzenie funkcji biblioteki klas języka C# przy użyciu usługi Azure Functions
Ważne
Wsparcie zostanie zakończone dla modelu procesu 10 listopada 2026 r. Zdecydowanie zalecamy przeprowadzenie migracji aplikacji do izolowanego modelu procesu roboczego w celu uzyskania pełnej obsługi.
Ten artykuł stanowi wprowadzenie do tworzenia usługi Azure Functions przy użyciu języka C# w bibliotekach klas platformy .NET. Te biblioteki klas są używane do uruchamiania w procesie przy użyciu środowiska uruchomieniowego usługi Functions. Funkcje platformy .NET mogą również uruchamiać _isolated ze środowiska uruchomieniowego usługi Functions, co zapewnia kilka zalet. Aby dowiedzieć się więcej, zobacz izolowany model procesu roboczego. Aby uzyskać kompleksowe porównanie tych dwóch modeli, zobacz Różnice między modelem procesowym a izolowanym modelem procesu roboczego.
Ważne
W tym artykule są obsługiwane funkcje biblioteki klas platformy .NET, które są uruchamiane w procesie w środowisku uruchomieniowym. Funkcje języka C# mogą również wyprowadzić proces i odizolować je od środowiska uruchomieniowego usługi Functions. Model izolowanego procesu roboczego to jedyny sposób uruchamiania wersji innych niż LTS aplikacji .NET i .NET Framework w bieżących wersjach środowiska uruchomieniowego usługi Functions. Aby dowiedzieć się więcej, zobacz Funkcje procesów procesu roboczego izolowanego platformy .NET. Aby zapoznać się z kompleksowym porównaniem procesu izolowanego procesu roboczego i funkcji platformy .NET w procesie, zobacz Różnice między procesem w procesie przetwarzania i izolowanym procesem roboczym platformy .NET Azure Functions.
Jako deweloper języka C# możesz również zainteresować się jednym z następujących artykułów:
Wprowadzenie | Pojęcia | Nauka z przewodnikiem/przykłady |
---|---|---|
Usługa Azure Functions obsługuje języki programowania skryptów w języku C# i C#. Jeśli szukasz wskazówek dotyczących korzystania z języka C# w witrynie Azure Portal, zobacz Dokumentację dla deweloperów skryptu języka C# (csx).
Obsługiwane wersje
Wersje środowiska uruchomieniowego usługi Functions obsługują określone wersje platformy .NET. Aby dowiedzieć się więcej na temat wersji usługi Functions, zobacz Omówienie wersji środowiska uruchomieniowego usługi Azure Functions. Obsługa wersji zależy również od tego, czy funkcje działają w procesie przetwarzania, czy izolowanego procesu roboczego.
Uwaga
Aby dowiedzieć się, jak zmienić wersję środowiska uruchomieniowego usługi Functions używaną przez aplikację funkcji, zobacz wyświetlanie i aktualizowanie bieżącej wersji środowiska uruchomieniowego.
W poniższej tabeli przedstawiono najwyższy poziom platformy .NET lub .NET Framework, który może być używany z określoną wersją usługi Functions.
Wersja środowiska uruchomieniowego usługi Functions | Model izolowanego procesu roboczego | Modelw procesie 5 |
---|---|---|
Funkcje 4.x1 | .NET 9.0 (wersja zapoznawcza) .NET 8.0 .NET 6.02 .NET Framework 4.83 |
.NET 8.0 .NET 6.02 |
Funkcje 1.x4 | nie dotyczy | .NET Framework 4.8 |
1 .NET 7 był wcześniej obsługiwany w modelu izolowanego procesu roboczego, ale 14 maja 2024 r. zakończyło się oficjalnym wsparciem .
2 .NET 6 kończy oficjalne wsparcie 12 listopada 2024 r.
3 Proces kompilacji wymaga również zestawu .NET SDK.
4 Zakończenie wsparcia dla wersji 1.x środowiska uruchomieniowego usługi Azure Functions 14 września 2026 r. Aby uzyskać więcej informacji, zobacz to ogłoszenie pomocy technicznej. Aby zapewnić ciągłą pełną obsługę, należy przeprowadzić migrację aplikacji do wersji 4.x.
5 Wsparcie kończy się dla modelu procesu 10 listopada 2026 r. Aby uzyskać więcej informacji, zobacz to ogłoszenie pomocy technicznej. Aby zapewnić ciągłą pełną obsługę, należy przeprowadzić migrację aplikacji do izolowanego modelu procesu roboczego.
Aby uzyskać najnowsze informacje o wersjach usługi Azure Functions, w tym o usunięciu określonych starszych wersji pomocniczych, monitoruj ogłoszenia usługi aplikacja systemu Azure.
Aktualizowanie do docelowej platformy .NET 8
Aplikacje korzystające z modelu przetwarzania mogą być przeznaczone dla platformy .NET 8, wykonując kroki opisane w tej sekcji. Jeśli jednak zdecydujesz się na wykonanie tej opcji, nadal należy rozpocząć planowanie migracji do izolowanego modelu procesów roboczych przed zakończeniem wsparcia dla modelu w procesie 10 listopada 2026 r.
Wiele aplikacji może zmienić konfigurację aplikacji funkcji na platformie Azure bez aktualizacji kodu lub ponownego wdrażania. Aby uruchomić platformę .NET 8 w modelu przetwarzania, wymagane są trzy konfiguracje:
- Ustawienie
FUNCTIONS_WORKER_RUNTIME
aplikacji musi być ustawione z wartością "dotnet". - Ustawienie
FUNCTIONS_EXTENSION_VERSION
aplikacji musi być ustawione z wartością "~4". - Ustawienie
FUNCTIONS_INPROC_NET8_ENABLED
aplikacji musi być ustawione z wartością "1". - Należy zaktualizować konfigurację stosu, aby odwoływać się do platformy .NET 8.
Obsługa platformy .NET 8 nadal używa wersji 4.x środowiska uruchomieniowego usługi Functions i nie jest wymagana żadna zmiana w skonfigurowanej wersji środowiska uruchomieniowego.
Aby zaktualizować projekt lokalny, najpierw upewnij się, że używasz najnowszych wersji narzędzi lokalnych. Następnie upewnij się, że projekt odwołuje się do wersji 4.4.0 lub nowszej zestawu Microsoft.NET.Sdk.Functions. Następnie możesz zmienić wartość TargetFramework
na "net8.0". Należy również zaktualizować local.settings.json
wartość , aby uwzględnić obie FUNCTIONS_WORKER_RUNTIME
wartości na "dotnet" i FUNCTIONS_INPROC_NET8_ENABLED
ustawić wartość "1".
Poniżej przedstawiono przykład minimalnego project
pliku z następującymi zmianami:
<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>
Poniżej przedstawiono przykład minimalnego local.settings.json
pliku z następującymi zmianami:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_INPROC_NET8_ENABLED": "1",
"FUNCTIONS_WORKER_RUNTIME": "dotnet"
}
}
Jeśli aplikacja używa Microsoft.Azure.DurableTask.Netherite.AzureFunctions
usługi , upewnij się, że jest przeznaczona dla wersji 1.5.3 lub nowszej. Ze względu na zmianę zachowania na platformie .NET 8 aplikacje ze starszymi wersjami pakietu będą zgłaszać niejednoznaczny wyjątek konstruktora.
Może być konieczne wprowadzenie innych zmian w aplikacji na podstawie obsługi wersji innych zależności.
Wersja 4.x środowiska uruchomieniowego usługi Functions zapewnia równoważne funkcje dla platform .NET 6 i .NET 8. Model w procesie nie zawiera dodatkowych funkcji ani aktualizacji, które integrują się z nowymi możliwościami platformy .NET 8. Na przykład środowisko uruchomieniowe nie obsługuje usług kluczy. Aby w pełni wykorzystać najnowsze możliwości i ulepszenia platformy .NET 8, należy przeprowadzić migrację do izolowanego modelu procesu roboczego.
Projekt biblioteki klas usługi Functions
W programie Visual Studio szablon projektu usługi Azure Functions tworzy projekt biblioteki klas języka C#zawierający następujące pliki:
- host.json — przechowuje ustawienia konfiguracji, które mają wpływ na wszystkie funkcje w projekcie podczas uruchamiania lokalnie lub na platformie Azure.
- local.settings.json — przechowuje ustawienia aplikacji i parametry połączenia używane podczas uruchamiania lokalnego. Ten plik zawiera wpisy tajne i nie jest publikowany w aplikacji funkcji na platformie Azure. Zamiast tego dodaj ustawienia aplikacji do aplikacji funkcji.
Podczas kompilowania projektu struktura folderów, która wygląda jak w poniższym przykładzie, jest generowana w katalogu wyjściowym kompilacji:
<framework.version>
| - bin
| - MyFirstFunction
| | - function.json
| - MySecondFunction
| | - function.json
| - host.json
Ten katalog jest wdrażany w aplikacji funkcji na platformie Azure. Rozszerzenia powiązań wymagane w wersji 2.x środowiska uruchomieniowego usługi Functions są dodawane do projektu jako pakiety NuGet.
Ważne
Proces kompilacji tworzy plik function.json dla każdej funkcji. Ten plik function.json nie ma być edytowany bezpośrednio. Nie można zmienić konfiguracji powiązania ani wyłączyć funkcji, edytując ten plik. Aby dowiedzieć się, jak wyłączyć funkcję, zobacz Jak wyłączyć funkcje.
Metody rozpoznawane jako funkcje
W bibliotece klas funkcja jest metodą z atrybutem FunctionName
i wyzwalacza, jak pokazano w poniższym przykładzie:
public static class SimpleExample
{
[FunctionName("QueueTrigger")]
public static void Run(
[QueueTrigger("myqueue-items")] string myQueueItem,
ILogger log)
{
log.LogInformation($"C# function processed: {myQueueItem}");
}
}
Atrybut FunctionName
oznacza metodę jako punkt wejścia funkcji. Nazwa musi być unikatowa w projekcie, zaczynać się literą i zawierać tylko litery, cyfry, _
i -
, do 127 znaków. Szablony projektów często tworzą metodę o nazwie Run
, ale nazwa metody może być dowolną prawidłową nazwą metody języka C#. W powyższym przykładzie pokazano używaną metodę statyczną, ale funkcje nie muszą być statyczne.
Atrybut wyzwalacza określa typ wyzwalacza i wiąże dane wejściowe z parametrem metody. Przykładowa funkcja jest wyzwalana przez komunikat kolejki, a komunikat kolejki jest przekazywany do metody w parametrze myQueueItem
.
Parametry sygnatury metody
Sygnatura metody może zawierać parametry inne niż używane z atrybutem wyzwalacza. Oto niektóre z innych parametrów, które można uwzględnić:
- Powiązania wejściowe i wyjściowe oznaczone jako takie przez dekorowanie ich za pomocą atrybutów.
- Parametr
ILogger
lubTraceWriter
(tylko wersja 1.x) na potrzeby rejestrowania. CancellationToken
Parametr do bezpiecznego zamykania.- Parametry wyrażeń powiązań w celu pobrania metadanych wyzwalacza.
Kolejność parametrów w podpisie funkcji nie ma znaczenia. Można na przykład umieścić parametry wyzwalacza przed lub po innych powiązaniach i można umieścić parametr rejestratora przed wyzwalaczem lub po parametrach wyzwalacza lub powiązania.
Powiązania wyjściowe
Funkcja może mieć zero lub wiele powiązań wyjściowych zdefiniowanych przy użyciu parametrów wyjściowych.
Poniższy przykład modyfikuje poprzedni, dodając powiązanie kolejki wyjściowej o nazwie myQueueItemCopy
. Funkcja zapisuje zawartość komunikatu, który wyzwala funkcję do nowego komunikatu w innej kolejce.
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;
}
}
Wartości przypisane do powiązań wyjściowych są zapisywane po zakończeniu działania funkcji. W funkcji można użyć więcej niż jednego powiązania wyjściowego, przypisując po prostu wartości do wielu parametrów wyjściowych.
Artykuły referencyjne powiązań (na przykład kolejki usługi Storage) wyjaśniają typy parametrów, których można używać z atrybutami wyzwalacza, danych wejściowych lub wyjściowych powiązania.
Przykładowe wyrażenia powiązań
Poniższy kod pobiera nazwę kolejki do monitorowania z ustawienia aplikacji i pobiera czas tworzenia komunikatów kolejki w parametrze insertionTime
.
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}");
}
}
Automatycznie wygenerowane function.json
Proces kompilacji tworzy plik function.json w folderze funkcji w folderze kompilacji. Jak wspomniano wcześniej, ten plik nie ma być edytowany bezpośrednio. Nie można zmienić konfiguracji powiązania ani wyłączyć funkcji, edytując ten plik.
Celem tego pliku jest dostarczenie informacji kontrolerowi skalowania do użycia w celu podejmowania decyzji dotyczących skalowania planu Zużycie. Z tego powodu plik zawiera tylko informacje o wyzwalaczu, a nie powiązania wejściowe/wyjściowe.
Wygenerowany plik function.json zawiera configurationSource
właściwość, która nakazuje środowisku uruchomieniowemu używanie atrybutów platformy .NET do powiązań, a nie function.json konfiguracji. Oto przykład:
{
"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
Generowanie plików function.json jest wykonywane przez pakiet NuGet Microsoft.NET.Sdk.Functions.
W poniższym przykładzie przedstawiono odpowiednie części .csproj
plików, które mają różne struktury docelowe tego samego Sdk
pakietu:
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.5.0" />
</ItemGroup>
Ważne
Począwszy od wersji 4.0.6517 narzędzi Core Tools, projekty modelu przetwarzania muszą odwoływać się do wersji 4.5.0 lub nowszej .Microsoft.NET.Sdk.Functions
Jeśli jest używana wcześniejsza wersja, func start
polecenie spowoduje błąd.
Sdk
Wśród zależności pakietów są wyzwalacze i powiązania. Projekt w wersji 1.x odwołuje się do wyzwalaczy i powiązań 1.x, ponieważ te wyzwalacze i powiązania są przeznaczone dla platformy .NET Framework, podczas gdy wyzwalacze i powiązania w wersji 4.x dotyczą platformy .NET Core.
Pakiet Sdk
zależy również od pliku Newtonsoft.Json i pośrednio w systemie WindowsAzure.Storage. Te zależności zapewniają, że projekt korzysta z wersji tych pakietów, które współpracują z wersją środowiska uruchomieniowego usługi Functions przeznaczoną dla projektu. Na przykład Newtonsoft.Json
ma wersję 11 dla programu .NET Framework 4.6.1, ale środowisko uruchomieniowe usługi Functions przeznaczone dla programu .NET Framework 4.6.1 jest zgodne tylko z wersją Newtonsoft.Json
9.0.1. Dlatego kod funkcji w tym projekcie musi również używać Newtonsoft.Json
wersji 9.0.1.
Kod źródłowy polecenia Microsoft.NET.Sdk.Functions
jest dostępny w repozytorium GitHub azure-functions-vs-build-sdk.
Lokalna wersja środowiska uruchomieniowego
Program Visual Studio używa narzędzi Azure Functions Core Tools do uruchamiania projektów usługi Functions na komputerze lokalnym. Core Tools to interfejs wiersza polecenia dla środowiska uruchomieniowego usługi Functions.
Jeśli zainstalujesz narzędzia Core Tools przy użyciu pakietu Instalatora Windows (MSI) lub narzędzia npm, nie ma to wpływu na wersję narzędzi Core Tools używaną przez program Visual Studio. W przypadku środowiska uruchomieniowego usługi Functions w wersji 1.x program Visual Studio przechowuje wersje narzędzi Core Tools w folderze %USERPROFILE%\AppData\Local\Azure.Functions.Cli i używa najnowszej przechowywanej tam wersji. W przypadku usługi Functions 4.x narzędzia Core Tools znajdują się w rozszerzeniu Azure Functions i Web Jobs Tools . W przypadku usługi Functions 1.x można zobaczyć, jaka wersja jest używana w danych wyjściowych konsoli podczas uruchamiania projektu usługi Functions:
[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
Aplikację funkcji można skompilować jako pliki binarne ReadyToRun. ReadyToRun to forma kompilacji przed czasem, która może poprawić wydajność uruchamiania, aby zmniejszyć wpływ zimnego startu podczas uruchamiania w planie Zużycie.
Funkcja ReadyToRun jest dostępna na platformie .NET 6 i nowszych wersjach oraz wymaga wersji 4.0 środowiska uruchomieniowego usługi Azure Functions.
Aby skompilować projekt jako ReadyToRun, zaktualizuj plik projektu, dodając <PublishReadyToRun>
elementy i <RuntimeIdentifier>
. Poniżej przedstawiono konfigurację publikowania w aplikacji funkcji systemu Windows 32-bitowej.
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<PublishReadyToRun>true</PublishReadyToRun>
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
</PropertyGroup>
Ważne
Począwszy od platformy .NET 6, dodano obsługę kompilacji Composite ReadyToRun. Zapoznaj się z ograniczeniami dotyczącymi platformy ReadyToRun Cross platform i architektury.
Możesz również skompilować aplikację za pomocą funkcji ReadyToRun z poziomu wiersza polecenia. Aby uzyskać więcej informacji, zobacz -p:PublishReadyToRun=true
opcję w dotnet publish
pliku .
Obsługiwane typy powiązań
Każde powiązanie ma własne obsługiwane typy; na przykład atrybut wyzwalacza obiektu blob można zastosować do parametru ciągu, parametru POCO, parametru CloudBlockBlob
lub dowolnego z kilku innych obsługiwanych typów. W artykule referencyjnym dotyczącym powiązań obiektów blob wymieniono wszystkie obsługiwane typy parametrów . Aby uzyskać więcej informacji, zobacz Wyzwalacze i powiązania oraz dokumentację referencyjną powiązań dla każdego typu powiązania.
Napiwek
Jeśli planujesz używać powiązań HTTP lub WebHook, zaplanuj uniknięcie wyczerpania portów HttpClient
, które mogą być spowodowane przez niewłaściwe utworzenie wystąpienia elementu . Aby uzyskać więcej informacji, zobacz Jak zarządzać połączeniami w usłudze Azure Functions.
Powiązanie z wartością zwracaną przez metodę
Możesz użyć wartości zwracanej metody dla powiązania wyjściowego, stosując atrybut do wartości zwracanej metody. Aby zapoznać się z przykładami, zobacz Wyzwalacze i powiązania.
Użyj wartości zwracanej tylko wtedy, gdy pomyślne wykonanie funkcji zawsze powoduje zwrócenie wartości do przekazania do powiązania wyjściowego. W przeciwnym razie użyj polecenia ICollector
lub IAsyncCollector
, jak pokazano w poniższej sekcji.
Zapisywanie wielu wartości wyjściowych
Aby zapisać wiele wartości w powiązaniu wyjściowym lub jeśli pomyślne wywołanie funkcji może nie spowodować przekazania niczego do powiązania wyjściowego, użyj ICollector
typów lub IAsyncCollector
. Te typy to kolekcje tylko do zapisu zapisywane w powiązaniu danych wyjściowych po zakończeniu działania metody.
W tym przykładzie wiele komunikatów kolejki jest zapisywanych w tej samej kolejce przy użyciu polecenia ICollector
:
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}");
}
}
Async
Aby utworzyć funkcję asynchroniczną, użyj słowa kluczowego async
i zwróć Task
obiekt.
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);
}
}
Nie można używać out
parametrów w funkcjach asynchronicznych. W przypadku powiązań wyjściowych należy zamiast tego użyć wartości zwracanej funkcji lub obiektu modułu zbierającego.
Tokeny anulowania
Funkcja może akceptować parametr CancellationToken , który umożliwia systemowi operacyjnemu powiadamianie o kodzie po zakończeniu działania funkcji. Możesz użyć tego powiadomienia, aby upewnić się, że funkcja nie zostanie nieoczekiwanie zakończona w sposób, który pozostawia dane w stanie niespójnym.
Rozważ przypadek, gdy masz funkcję przetwarzającą komunikaty w partiach. Następująca funkcja wyzwalana przez usługę Azure Service Bus przetwarza tablicę obiektów ServiceBusReceivedMessage , która reprezentuje partię komunikatów przychodzących do przetworzenia przez wywołanie określonej funkcji:
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}");
}
}
}
}
Rejestrowanie
W kodzie funkcji można zapisywać dane wyjściowe w dziennikach, które są wyświetlane jako ślady w usłudze Application Insights. Zalecanym sposobem zapisu w dziennikach jest dołączenie parametru typu ILogger, który jest zwykle nazwany log
. Używana wersja 1.x środowiska uruchomieniowego TraceWriter
usługi Functions, która również zapisuje w usłudze Application Insights, ale nie obsługuje rejestrowania strukturalnego. Nie używaj Console.Write
funkcji do zapisywania dzienników, ponieważ te dane nie są przechwytywane przez usługę Application Insights.
ILogger
W definicji funkcji dołącz parametr ILogger , który obsługuje rejestrowanie strukturalne.
ILogger
Obiekt wywołuje Log<level>
metody rozszerzenia w usłudze ILogger w celu utworzenia dzienników. Poniższy kod zapisuje dzienniki Information
z kategorią Function.<YOUR_FUNCTION_NAME>.User.
:
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, ILogger logger)
{
logger.LogInformation("Request for item with key={itemKey}.", id);
Aby dowiedzieć się więcej o sposobie implementacji ILogger
usługi Functions, zobacz Zbieranie danych telemetrycznych. Kategorie poprzedzone Function
założeniem ILogger
, że używasz wystąpienia. Jeśli zdecydujesz się zamiast tego użyć ILogger<T>
, nazwa kategorii może zamiast tego być oparta na .T
Rejestrowanie strukturalne
Kolejność symboli zastępczych, a nie ich nazw, określa, które parametry są używane w komunikacie dziennika. Załóżmy, że masz następujący kod:
string partitionKey = "partitionKey";
string rowKey = "rowKey";
logger.LogInformation("partitionKey={partitionKey}, rowKey={rowKey}", partitionKey, rowKey);
Jeśli zachowasz ten sam ciąg komunikatu i odwrócisz kolejność parametrów, wynikowy tekst komunikatu będzie miał wartości w nieprawidłowych miejscach.
Symbole zastępcze są obsługiwane w ten sposób, aby można było wykonywać rejestrowanie strukturalne. Usługa Application Insights przechowuje pary nazwa-wartość parametru i ciąg komunikatu. Wynikiem jest to, że argumenty komunikatu stają się polami, na których można wykonywać zapytania.
Jeśli wywołanie metody rejestratora wygląda jak w poprzednim przykładzie, możesz wykonać zapytanie względem pola customDimensions.prop__rowKey
. Prefiks prop__
jest dodawany, aby upewnić się, że nie ma żadnych kolizji między polami, które dodaje środowisko uruchomieniowe, a polami dodanymi przez kod funkcji.
Możesz również wykonać zapytanie dotyczące oryginalnego ciągu komunikatu, odwołując się do pola customDimensions.prop__{OriginalFormat}
.
Oto przykładowa reprezentacja customDimensions
danych w formacie JSON:
{
"customDimensions": {
"prop__{OriginalFormat}":"C# Queue trigger function processed: {message}",
"Category":"Function",
"LogLevel":"Information",
"prop__message":"c9519cbf-b1e6-4b9b-bf24-cb7d10b1bb89"
}
}
Rejestrowanie telemetrii niestandardowej
Istnieje specyficzna dla funkcji wersja zestawu SDK usługi Application Insights, której można użyć do wysyłania niestandardowych danych telemetrycznych z funkcji do usługi Application Insights: Microsoft.Azure.WebJobs.Logging.ApplicationInsights. Użyj następującego polecenia w wierszu polecenia, aby zainstalować ten pakiet:
dotnet add package Microsoft.Azure.WebJobs.Logging.ApplicationInsights --version <VERSION>
W tym poleceniu zastąp <VERSION>
element wersją tego pakietu, która obsługuje zainstalowaną wersję zadań Microsoft.Azure.WebJobs.
W poniższych przykładach języka C# użyto niestandardowego interfejsu API telemetrii. Przykład dotyczy biblioteki klas platformy .NET, ale kod usługi Application Insights jest taki sam dla skryptu języka C#.
Wersja 2.x i nowsze środowiska uruchomieniowego używają nowszych funkcji w usłudze Application Insights, aby automatycznie korelować dane telemetryczne z bieżącą operacją. Nie ma potrzeby ręcznego ustawiania operacji Id
, ParentId
lub Name
pól.
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());
}
}
}
W tym przykładzie niestandardowe dane metryk są agregowane przez hosta przed wysłaniem ich do tabeli customMetrics. Aby dowiedzieć się więcej, zobacz dokumentację getmetric w usłudze Application Insights.
W przypadku uruchamiania lokalnego APPINSIGHTS_INSTRUMENTATIONKEY
należy dodać ustawienie z kluczem usługi Application Insights do pliku local.settings.json .
Nie wywołujej wywołań TrackRequest
ani StartOperation<RequestTelemetry>
dlatego, że zobaczysz zduplikowane żądania wywołania funkcji. Środowisko uruchomieniowe usługi Functions automatycznie śledzi żądania.
Nie ustawiaj wartości telemetryClient.Context.Operation.Id
. To ustawienie globalne powoduje nieprawidłową korelację, gdy wiele funkcji jest uruchomionych jednocześnie. Zamiast tego utwórz nowe wystąpienie telemetrii (DependencyTelemetry
, EventTelemetry
) i zmodyfikuj jego Context
właściwość. Następnie przekaż wystąpienie telemetrii do odpowiedniej Track
metody w dniu TelemetryClient
(TrackDependency()
, TrackEvent()
, TrackMetric()
). Ta metoda zapewnia, że dane telemetryczne mają poprawne szczegóły korelacji dla wywołania bieżącej funkcji.
Testowanie funkcji
W poniższych artykułach pokazano, jak uruchomić lokalnie funkcję biblioteki klas języka C# w procesie na potrzeby testowania:
Zmienne środowiskowe
Aby uzyskać zmienną środowiskową lub wartość ustawienia aplikacji, użyj metody System.Environment.GetEnvironmentVariable
, jak pokazano w poniższym przykładzie kodu:
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);
}
}
Ustawienia aplikacji można odczytywać ze zmiennych środowiskowych zarówno podczas programowania lokalnego, jak i podczas uruchamiania na platformie Azure. Podczas tworzenia aplikacji lokalnie ustawienia aplikacji pochodzą z Values
kolekcji w pliku local.settings.json . W obu środowiskach, lokalnie i na platformie Azure pobiera GetEnvironmentVariable("<app setting name>")
wartość nazwanego ustawienia aplikacji. Na przykład po uruchomieniu lokalnie zostanie zwrócona wartość "Moja nazwa witryny", jeśli plik local.settings.json zawiera { "Values": { "WEBSITE_SITE_NAME": "My Site Name" } }
wartość .
Właściwość System.Configuration.ConfigurationManager.AppSettings jest alternatywnym interfejsem API służącym do pobierania wartości ustawień aplikacji, ale zalecamy użycie go GetEnvironmentVariable
w sposób pokazany tutaj.
Wiązanie w czasie wykonywania
W języku C# i innych językach platformy .NET można użyć wzorca powiązania imperatywnego, w przeciwieństwie do powiązań deklaratywnych w atrybutach. Powiązanie imperatywne jest przydatne, gdy parametry powiązania muszą być obliczane w czasie wykonywania, a nie w czasie projektowania. Za pomocą tego wzorca można powiązać obsługiwane powiązania wejściowe i wyjściowe na bieżąco w kodzie funkcji.
Zdefiniuj powiązanie imperatywne w następujący sposób:
Nie dołączaj atrybutu do podpisu funkcji dla żądanych powiązań imperatywnych.
Przekaż parametr
Binder binder
wejściowy lubIBinder binder
.Użyj następującego wzorca języka C#, aby wykonać powiązanie danych.
using (var output = await binder.BindAsync<T>(new BindingTypeAttribute(...))) { ... }
BindingTypeAttribute
to atrybut platformy .NET, który definiuje powiązanie iT
jest typem wejściowym lub wyjściowym obsługiwanym przez ten typ powiązania.T
nie może być typem parametruout
(takim jakout JObject
). Na przykład powiązanie wyjściowe tabeli Mobile Apps obsługuje sześć typów danych wyjściowych, ale można użyć tylko metody ICollector T> lub IAsyncCollector<<T> z powiązaniem imperatywnym.
Przykład pojedynczego atrybutu
Poniższy przykładowy kod tworzy powiązanie wyjściowe obiektu blob usługi Storage ze ścieżką obiektu blob zdefiniowaną w czasie wykonywania, a następnie zapisuje ciąg w obiekcie blob.
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!");
};
}
}
Obiekt BlobAttribute definiuje powiązanie wejściowe lub wyjściowe obiektu blob usługi Storage, a TextWriter jest obsługiwanym typem powiązania wyjściowego.
Przykład wielu atrybutów
Powyższy przykład pobiera ustawienie aplikacji dla głównego konta magazynu aplikacji funkcji parametry połączenia (czyli AzureWebJobsStorage
). Możesz określić niestandardowe ustawienie aplikacji, które ma być używane dla konta magazynu, dodając atrybut StorageAccountAttribute i przekazując tablicę atrybutów do BindAsync<T>()
elementu . Użyj parametru Binder
, a nie IBinder
. Na przykład:
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!!");
}
}
}
Wyzwalacze i powiązania
W tej tabeli przedstawiono powiązania obsługiwane w głównych wersjach środowiska uruchomieniowego usługi Azure Functions:
Typ | 1.x1 | 2.x i nowsze2 | Wyzwalacz | Dane wejściowe | Dane wyjściowe |
---|---|---|---|---|---|
Blob Storage | ✔ | ✔ | ✔ | ✔ | ✔ |
Azure Cosmos DB | ✔ | ✔ | ✔ | ✔ | ✔ |
Azure Data Explorer | ✔ | ✔ | ✔ | ||
Azure SQL | ✔ | ✔ | ✔ | ✔ | |
Dapr4 | ✔ | ✔ | ✔ | ✔ | |
Event Grid | ✔ | ✔ | ✔ | ✔ | |
Event Hubs | ✔ | ✔ | ✔ | ✔ | |
Http i elementy webhook | ✔ | ✔ | ✔ | ✔ | |
IoT Hub | ✔ | ✔ | ✔ | ||
Kafka3 | ✔ | ✔ | ✔ | ||
Mobile Apps | ✔ | ✔ | ✔ | ||
Notification Hubs | ✔ | ✔ | |||
Queue Storage | ✔ | ✔ | ✔ | ✔ | |
Redis | ✔ | ✔ | |||
RabbitMQ3 | ✔ | ✔ | ✔ | ||
SendGrid | ✔ | ✔ | ✔ | ||
Service Bus | ✔ | ✔ | ✔ | ✔ | |
SignalR | ✔ | ✔ | ✔ | ✔ | |
Table Storage | ✔ | ✔ | ✔ | ✔ | |
Czasomierz | ✔ | ✔ | ✔ | ||
Twilio | ✔ | ✔ | ✔ |
Uwagi:
- Pomoc techniczna zakończy się w wersji 1.x środowiska uruchomieniowego usługi Azure Functions 14 września 2026 r. Zdecydowanie zalecamy przeprowadzenie migracji aplikacji do wersji 4.x w celu uzyskania pełnej pomocy technicznej.
- Począwszy od środowiska uruchomieniowego w wersji 2.x, wszystkie powiązania z wyjątkiem protokołu HTTP i czasomierza muszą być zarejestrowane. Zobacz Rejestrowanie rozszerzeń powiązań.
- Wyzwalacze nie są obsługiwane w planie Zużycie. Wymaga wyzwalaczy opartych na środowisku uruchomieniowym.
- Obsługiwane tylko w rozwiązaniach Kubernetes, IoT Edge i innych trybach hostowanych samodzielnie.