Справочник разработчика C# по функциям AzureAzure Functions C# developer reference

Эта статья описывает разработку функций Azure с помощью C# в библиотеках классов .NET.This article is an introduction to developing Azure Functions by using C# in .NET class libraries.

Разработчик C# может также заинтересовать одну из следующих статей:As a C# developer, you may also be interested in one of the following articles:

Начало работыGetting started Основные понятияConcepts Интерактивное обучение и примерыGuided learning/samples

Решение "Функции Azure" поддерживает языки программирования C# и скрипт C#.Azure Functions supports C# and C# script programming languages. Рекомендации по использованию C# на портале Azure см. в справочнике разработчика скриптов C# (.csx).If you're looking for guidance on using C# in the Azure portal, see C# script (.csx) developer reference.

Поддерживаемые версииSupported versions

Версии среды выполнения функций работают с конкретными версиями .NET.Versions of the Functions runtime work with specific versions of .NET. В следующей таблице показан самый высокий уровень .NET Core, .NET Framework и .NET Core, которые можно использовать с определенной версией функций в проекте.The following table shows the highest level of .NET Core and .NET Framework and .NET Core that can be used with a specific version of Functions in your project.

Версия среды выполнения функцийFunctions runtime version Максимальная версия .NETMax .NET version
Функции 3. xFunctions 3.x .NET Core 3.1.NET Core 3.1
Функции 2.xFunctions 2.x .NET Core 2.2.NET Core 2.2
Функции 1.xFunctions 1.x .NET Framework 4.7.NET Framework 4.7

Дополнительные сведения см. в статье Обзор версий среды выполнения функций Azure .To learn more, see Azure Functions runtime versions overview

Проект библиотеки классов функцийFunctions class library project

В Visual Studio шаблон проекта Функции Azure создает проект библиотеки классов C#, содержащий следующие файлы:In Visual Studio, the Azure Functions project template creates a C# class library project that contains the following files:

  • host.json — хранит параметры конфигурации, которые влияют на все функции в проекте при выполнении в локальной среде или в Azure.host.json - stores configuration settings that affect all functions in the project when running locally or in Azure.
  • local.settings.json — хранит параметры приложений и строки подключения, которые используются при выполнении в локальной среде.local.settings.json - stores app settings and connection strings that are used when running locally. Этот файл содержит секретные данные и не будет опубликован в приложении-функции в Azure.This file contains secrets and isn't published to your function app in Azure. Вместо этого добавьте параметры приложения в приложение функции.Instead, add app settings to your function app.

При построении проекта структура папок, которая выглядит следующим образом, создается в выходном каталоге сборки:When you build the project, a folder structure that looks like the following example is generated in the build output directory:

<framework.version>
 | - bin
 | - MyFirstFunction
 | | - function.json
 | - MySecondFunction
 | | - function.json
 | - host.json

Этот каталог — то, что будет развернуто в вашем приложении-функции в Azure.This directory is what gets deployed to your function app in Azure. Расширения привязки, необходимые в версии 2.x среды выполнения функций, добавляются в проект как пакеты NuGet.The binding extensions required in version 2.x of the Functions runtime are added to the project as NuGet packages.

Важно!

Процесс сборки создает файл function.json для каждой функции.The build process creates a function.json file for each function. Этот файл function.json не предназначен для непосредственного редактирования.This function.json file is not meant to be edited directly. Невозможно изменить конфигурацию привязки или отключить функцию путем редактирования этого файла.You can't change binding configuration or disable the function by editing this file. Чтобы узнать, как отключить функцию, см. раздел Отключение функций.To learn how to disable a function, see How to disable functions.

Методы, распознаваемые как функцииMethods recognized as functions

В библиотеке классов функция — это статический метод с FunctionName и атрибутом триггера, как показано в следующем примере:In a class library, a function is a static method with a FunctionName and a trigger attribute, as shown in the following example:

public static class SimpleExample
{
    [FunctionName("QueueTrigger")]
    public static void Run(
        [QueueTrigger("myqueue-items")] string myQueueItem, 
        ILogger log)
    {
        log.LogInformation($"C# function processed: {myQueueItem}");
    }
} 

Атрибут FunctionName помечает метод как точку входа функции.The FunctionName attribute marks the method as a function entry point. Имя должно быть уникальным в пределах проекта, начинаться с буквы и содержать только буквы, цифры, _ и - , до 127 символов.The name must be unique within a project, start with a letter and only contain letters, numbers, _, and -, up to 127 characters in length. Шаблоны проектов часто создают метод Run, но метод может иметь любое допустимое имя для метода C#.Project templates often create a method named Run, but the method name can be any valid C# method name.

Атрибут триггера указывает тип триггера и привязывает входные данные к параметру метода.The trigger attribute specifies the trigger type and binds input data to a method parameter. Пример функции срабатывает по сообщению очереди, а сообщение очереди передается методу в параметре myQueueItem.The example function is triggered by a queue message, and the queue message is passed to the method in the myQueueItem parameter.

Параметры сигнатуры методаMethod signature parameters

Сигнатура метода может содержать параметры, отличные от используемых с атрибутом триггера.The method signature may contain parameters other than the one used with the trigger attribute. Ниже приведены некоторые дополнительные параметры, которые можно включить:Here are some of the additional parameters that you can include:

Порядок параметров в сигнатуре функции не имеет значения.The order of parameters in the function signature does not matter. Например, можно указать параметры триггера до или после других привязок, а параметр для средства ведения журнала — до или после параметров триггера или привязки.For example, you can put trigger parameters before or after other bindings, and you can put the logger parameter before or after trigger or binding parameters.

Пример выходной привязкиOutput binding example

В следующем примере изменяется предыдущий путем добавления привязки очереди вывода.The following example modifies the preceding one by adding an output queue binding. Функция записывает сообщение очереди, запускающее функцию для нового сообщения очереди в другую очередь.The function writes the queue message that triggers the function to a new queue message in a different queue.

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

В справочных статьях по привязкам (например, Привязки хранилища очередей Azure для службы "Функции Azure") объясняется, какие типы параметров можно использовать с триггерами, а также с атрибутами входных или выходных привязок.The binding reference articles (Storage queues, for example) explain which parameter types you can use with trigger, input, or output binding attributes.

Пример выражений привязкиBinding expressions example

Приведенный ниже код позволяет получить имя очереди для мониторинга из настроек приложения и время создания сообщения очереди в параметре insertionTime.The following code gets the name of the queue to monitor from an app setting, and it gets the queue message creation time in the insertionTime parameter.

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

Автоматически созданный файл function.jsonAutogenerated function.json

Процесс сборки создает файл function.json в папке функции в папке сборки.The build process creates a function.json file in a function folder in the build folder. Как уже говорилось, этот файл не предназначен для непосредственного редактирования.As noted earlier, this file is not meant to be edited directly. Невозможно изменить конфигурацию привязки или отключить функцию путем редактирования этого файла.You can't change binding configuration or disable the function by editing this file.

Цель этого файла — предоставить сведения контроллеру масштабирования, который будет использоваться для принятия решений о масштабировании в плане потребления.The purpose of this file is to provide information to the scale controller to use for scaling decisions on the Consumption plan. По этой причине файл содержит только сведения о триггерах, но не о входных или выходных привязках.For this reason, the file only has trigger info, not input or output bindings.

Создаваемый файл function.json содержит свойство configurationSource, которое указывает среде выполнения использовать атрибуты .NET для привязок, вместо конфигурации function.json.The generated function.json file includes a configurationSource property that tells the runtime to use .NET attributes for bindings, rather than function.json configuration. Пример:Here's an example:

{
  "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.FunctionsMicrosoft.NET.Sdk.Functions

Создание файла function.json выполняется пакетом NuGet Microsoft.NET.Sdk.Functions.The function.json file generation is performed by the NuGet package Microsoft.NET.Sdk.Functions.

Тот же пакет используется в обеих версиях (1.x и 2.x) среды выполнения Функций.The same package is used for both version 1.x and 2.x of the Functions runtime. Проекты 1.x и 2.x отличаются только требуемой версией .NET Framework.The target framework is what differentiates a 1.x project from a 2.x project. Ниже приведены фрагменты файлов .csproj с разными требуемыми версиями .NET Framework и одним пакетом Sdk.Here are the relevant parts of .csproj files, showing different target frameworks and the same Sdk package:

<PropertyGroup>
  <TargetFramework>netcoreapp2.1</TargetFramework>
  <AzureFunctionsVersion>v2</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
  <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.8" />
</ItemGroup>

К зависимостям пакетов Sdk относятся триггеры и привязки.Among the Sdk package dependencies are triggers and bindings. Проект 1. x ссылается на триггеры и привязки 1. x, так как эти триггеры и привязки предназначены для .NET Framework, а триггеры и привязки 2. x предназначены для .NET Core.A 1.x project refers to 1.x triggers and bindings because those triggers and bindings target the .NET Framework, while 2.x triggers and bindings target .NET Core.

Пакет Sdk также зависит от пакета Newtonsoft.Json и косвенно от пакета WindowsAzure.Storage.The Sdk package also depends on Newtonsoft.Json, and indirectly on WindowsAzure.Storage. Эти зависимости гарантируют, что проект использует версии пакетов, совместимые с версией среды выполнения Функций, для которой он предназначен.These dependencies make sure that your project uses the versions of those packages that work with the Functions runtime version that the project targets. Например, при использовании платформы .NET Framework 4.6.1 пакет Newtonsoft.Json имеет версию 11, но среда выполнения Функций, предназначенная для платформы .NET Framework 4.6.1, совместима только с пакетом Newtonsoft.Json версии 9.0.1.For example, Newtonsoft.Json has version 11 for .NET Framework 4.6.1, but the Functions runtime that targets .NET Framework 4.6.1 is only compatible with Newtonsoft.Json 9.0.1. Поэтому код функции в этом проекте также должен использовать пакет Newtonsoft.Json версии 9.0.1.So your function code in that project also has to use Newtonsoft.Json 9.0.1.

Исходный код пакета Microsoft.NET.Sdk.Functions доступен в репозитории GitHub azure-functions-vs-build-sdk.The source code for Microsoft.NET.Sdk.Functions is available in the GitHub repo azure-functions-vs-build-sdk.

Версия среды выполненияRuntime version

Visual Studio выполняет проекты Функций с помощью основных инструментов Функций Azure.Visual Studio uses the Azure Functions Core Tools to run Functions projects. Основные инструменты — это интерфейс командной строки среды выполнения Функций.The Core Tools is a command-line interface for the Functions runtime.

Если вы установите основные инструменты с помощью npm, это не повлияет на версию инструментов, используемую Visual Studio.If you install the Core Tools by using npm, that doesn't affect the Core Tools version used by Visual Studio. Версии основных инструментов среды выполнения Функций 1.x хранятся в файле %USERPROFILE%\AppData\Local\Azure.Functions.Cli. Visual Studio использует последнюю версию.For the Functions runtime version 1.x, Visual Studio stores Core Tools versions in %USERPROFILE%\AppData\Local\Azure.Functions.Cli and uses the latest version stored there. Основные инструменты Функций 2.x включены в расширение Инструменты для Функций Azure и веб-заданий.For Functions 2.x, the Core Tools are included in the Azure Functions and Web Jobs Tools extension. Используемую в 1.x и 2.x версию можно просмотреть в выходных данных консоли при запуске проекта Функций:For both 1.x and 2.x, you can see what version is being used in the console output when you run a Functions project:

[3/1/2018 9:59:53 AM] Starting Host (HostId=contoso2-1518597420, Version=2.0.11353.0, ProcessId=22020, Debug=False, Attempt=0, FunctionsExtensionVersion=)

ReadyToRunReadyToRun

Приложение функции можно скомпилировать как двоичные файлы реадиторун.You can compile your function app as ReadyToRun binaries. Реадиторун является формой предварительной компиляции, которая может повысить производительность при запуске, чтобы снизить влияние холодного запуска при запуске в плане потребления.ReadyToRun is a form of ahead-of-time compilation that can improve startup performance to help reduce the impact of cold-start when running in a Consumption plan.

Реадиторун доступен в .NET 3,0 и требует версии 3,0 среды выполнения функций Azure.ReadyToRun is available in .NET 3.0 and requires version 3.0 of the Azure Functions runtime.

Чтобы скомпилировать проект как Реадиторун, обновите файл проекта, добавив <PublishReadyToRun> элементы и <RuntimeIdentifier> .To compile your project as ReadyToRun, update your project file by adding the <PublishReadyToRun> and <RuntimeIdentifier> elements. Ниже приведена конфигурация для публикации в приложении-функции Windows 32 bit.The following is the configuration for publishing to a Windows 32-bit function app.

<PropertyGroup>
  <TargetFramework>netcoreapp3.1</TargetFramework>
  <AzureFunctionsVersion>v3</AzureFunctionsVersion>
  <PublishReadyToRun>true</PublishReadyToRun>
  <RuntimeIdentifier>win-x86</RuntimeIdentifier>
</PropertyGroup>

Важно!

Реадиторун сейчас не поддерживает перекрестную компиляцию.ReadyToRun currently doesn't support cross-compilation. Приложение должно быть построено на той же платформе, что и целевой объект развертывания.You must build your app on the same platform as the deployment target. Кроме того, обратите внимание на «разрядность», настроенную в приложении-функции.Also, pay attention to the "bitness" that is configured in your function app. Например, если приложение-функция в Azure — Windows 64 bit, необходимо скомпилировать приложение в Windows, используя в win-x64 качестве идентификатора среды выполнения.For example, if your function app in Azure is Windows 64-bit, you must compile your app on Windows with win-x64 as the runtime identifier.

Вы также можете создать приложение с помощью Реадиторун из командной строки.You can also build your app with ReadyToRun from the command line. Дополнительные сведения см. в описании -p:PublishReadyToRun=true параметра в разделе dotnet publish .For more information, see the -p:PublishReadyToRun=true option in dotnet publish.

Поддерживаемые типы для привязокSupported types for bindings

Все привязки поддерживают определенные типы. Например, атрибут триггера большого двоичного объекта можно применить к строковому параметру, параметру POCO, параметру CloudBlockBlob или любому из нескольких других поддерживаемых типов.Each binding has its own supported types; for instance, a blob trigger attribute can be applied to a string parameter, a POCO parameter, a CloudBlockBlob parameter, or any of several other supported types. В справочной статье о привязках для больших двоичных объектов содержится список всех поддерживаемых типов параметров.The binding reference article for blob bindings lists all supported parameter types. Дополнительные сведения см. в статье о триггерах и привязках и в справочной документации по каждому типу привязки.For more information, see Triggers and bindings and the binding reference docs for each binding type.

Совет

Если вы планируете использовать привязки HTTP или веб-перехватчика, спланируйте работу так, чтобы избежать нехватки портов, которая может возникнуть в результате неправильной установки HttpClient.If you plan to use the HTTP or WebHook bindings, plan to avoid port exhaustion that can be caused by improper instantiation of HttpClient. См. дополнительные сведения об управлении подключениями в службе "Функции Azure".For more information, see How to manage connections in Azure Functions.

Привязка к возвращаемому значению методаBinding to method return value

Возвращаемое значение метода можно использовать для привязки выходных данных. Для этого примените атрибут к возвращаемому значению метода.You can use a method return value for an output binding, by applying the attribute to the method return value. Примеры см. в статье о триггерах и привязках.For examples, see Triggers and bindings.

Используйте возвращаемое значение, только если в результате успешного выполнения функции всегда возвращается значение для передачи в привязку для вывода.Use the return value only if a successful function execution always results in a return value to pass to the output binding. В противном случае используйте ICollector или IAsyncCollector, как указано в следующем разделе.Otherwise, use ICollector or IAsyncCollector, as shown in the following section.

Написание нескольких значений выходных данныхWriting multiple output values

Чтобы записать несколько значений в привязку для вывода или если после успешного вызова функции не возвращается значение для передачи в привязку для вывода, используйте типы ICollector или IAsyncCollector.To write multiple values to an output binding, or if a successful function invocation might not result in anything to pass to the output binding, use the ICollector or IAsyncCollector types. Эти типы представляют собой доступные только для записи коллекции, записываемые в выходную привязку по завершении метода.These types are write-only collections that are written to the output binding when the method completes.

В следующем примере записываются несколько сообщений очереди в ту же очередь с помощью ICollector:This example writes multiple queue messages into the same queue using 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

Чтобы сделать функцию асинхронной, используйте ключевое слово async и верните объект Task.To make a function asynchronous, use the async keyword and return a Task object.

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

Вы не можете использовать параметры out в асинхронных функциях.You can't use out parameters in async functions. Вместо этих параметров для выходных привязок используйте возвращаемое значение функции или объект сборщика.For output bindings, use the function return value or a collector object instead.

Токены отменыCancellation tokens

Функция может принимать параметр CancellationToken, который позволяет операционной системе передавать в ваш код сведения о том, что выполнение функции будет завершено.A function can accept a CancellationToken parameter, which enables the operating system to notify your code when the function is about to be terminated. Это уведомление можно использовать для предотвращения ситуации, когда выполнение функции завершается неожиданно, оставляя данные в несогласованном состоянии.You can use this notification to make sure the function doesn't terminate unexpectedly in a way that leaves data in an inconsistent state.

В следующем примере показано, как проверить, не приближается ли завершение выполнения функции.The following example shows how to check for impending function termination.

public static class CancellationTokenExample
{
    public static void Run(
        [QueueTrigger("inputqueue")] string inputText,
        TextWriter logger,
        CancellationToken token)
    {
        for (int i = 0; i < 100; i++)
        {
            if (token.IsCancellationRequested)
            {
                logger.WriteLine("Function was cancelled at iteration {0}", i);
                break;
            }
            Thread.Sleep(5000);
            logger.WriteLine("Normal processing for queue message={0}", inputText);
        }
    }
}

LoggingLogging

В коде функции можно записывать выходные данные в журналы, которые отображаются как трассировки в Application Insights.In your function code, you can write output to logs that appear as traces in Application Insights. Рекомендуемый способ записи в журналы — включить параметр типа ILogger, который обычно называется log .The recommended way to write to the logs is to include a parameter of type ILogger, which is typically named log. Версия 1. x используемой среды выполнения функций TraceWriter , которая также выполняет запись в Application Insights, но не поддерживает структурированное ведение журнала.Version 1.x of the Functions runtime used TraceWriter, which also writes to Application Insights, but doesn't support structured logging. Не используйте Console.Write для записи журналов, так как эти данные не фиксируются Application Insights.Don't use Console.Write to write your logs, since this data isn't captured by Application Insights.

ILoggerILogger

В определении функции включите параметр ILogger , который поддерживает структурированное ведение журнала.In your function definition, include an ILogger parameter, which supports structured logging.

Объект ILogger позволяет вызывать для создания журналов методы расширения ILoggerLog<level>.With an ILogger object, you call Log<level> extension methods on ILogger to create logs. Следующий код записывает Information журналы с категорией Function.<YOUR_FUNCTION_NAME>.User. :The following code writes Information logs with category Function.<YOUR_FUNCTION_NAME>.User.:

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, ILogger logger)
{
    logger.LogInformation("Request for item with key={itemKey}.", id);

Структурированное ведение журналаStructured logging

Использование параметров в сообщении журнала определяется порядком заполнителей, а не их именами.The order of placeholders, not their names, determines which parameters are used in the log message. Предположим, что у вас есть следующий код:Suppose you have the following code:

string partitionKey = "partitionKey";
string rowKey = "rowKey";
logger.LogInformation("partitionKey={partitionKey}, rowKey={rowKey}", partitionKey, rowKey);

Если вы примените эту же строку сообщения с обратным порядком параметров, в тексте сообщения значения окажутся на неправильных местах.If you keep the same message string and reverse the order of the parameters, the resulting message text would have the values in the wrong places.

Такой метод обработки заполнителей позволяет выполнять структурированное ведение журналов.Placeholders are handled this way so that you can do structured logging. Application Insights сохраняет не только строку сообщения, но и параметры в формате пар "имя-значение".Application Insights stores the parameter name-value pairs and the message string. Благодаря этому все аргументы сообщения становятся полями, по которым можно выполнять запросы.The result is that the message arguments become fields that you can query on.

Если используется метод ведения журнала из предыдущего примера, вы сможете отправить запрос поля customDimensions.prop__rowKey.If your logger method call looks like the previous example, you can query the field customDimensions.prop__rowKey. При этом добавляется префикс prop__, чтобы не возникало конфликтов между полями, которые добавляет среда выполнения и которые добавляет код вашей функции.The prop__ prefix is added to ensure there are no collisions between fields the runtime adds and fields your function code adds.

Исходную строку сообщения можно получить, указав в запросе поле customDimensions.prop__{OriginalFormat}.You can also query on the original message string by referencing the field customDimensions.prop__{OriginalFormat}.

Ниже приведен пример JSON-представления для данных customDimensions.Here's a sample JSON representation of customDimensions data:

{
  "customDimensions": {
    "prop__{OriginalFormat}":"C# Queue trigger function processed: {message}",
    "Category":"Function",
    "LogLevel":"Information",
    "prop__message":"c9519cbf-b1e6-4b9b-bf24-cb7d10b1bb89"
  }
}

Раздел о записи пользовательской телеметрии в функциях C#Log custom telemetry in C# functions

Для отправки пользовательских данных телеметрии из функций в Application Insights можно использовать зависящую от функций версию пакета SDK Application Insights: Microsoft.Azure.WebJobs.Logging.ApplicationInsights.There is a Functions-specific version of the Application Insights SDK that you can use to send custom telemetry data from your functions to Application Insights: Microsoft.Azure.WebJobs.Logging.ApplicationInsights. Для установки этого пакета используйте следующую команду из командной строки:Use the following command from the command prompt to install this package:

dotnet add package Microsoft.Azure.WebJobs.Logging.ApplicationInsights --version <VERSION>

В этой команде замените <VERSION> версией этого пакета, которая поддерживает установленную версию Microsoft.Azure.WebJobs.In this command, replace <VERSION> with a version of this package that supports your installed version of Microsoft.Azure.WebJobs.

В следующем примере C# используется настраиваемый интерфейс API телеметрии.The following C# examples uses the custom telemetry API. Пример приведен для библиотеки классов .NET, но код Application Insights в скрипте C# будет точно таким же.The example is for a .NET class library, but the Application Insights code is the same for C# script.

Среда выполнения версии 2.x или более поздних использует новые функции в Application Insights для выполнения автоматической корреляции данных телеметрии с текущей операцией.Version 2.x and later versions of the runtime use newer features in Application Insights to automatically correlate telemetry with the current operation. Нет необходимости вручную задавать для операции поля Id, ParentId или Name.There's no need to manually set the operation Id, ParentId, or Name fields.

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

В этом примере пользовательские данные метрики объединяются узлом перед отправкой в таблицу customMetrics.In this example, the custom metric data gets aggregated by the host before being sent to the customMetrics table. Дополнительные сведения см. в документации по Application Insights.To learn more, see the GetMetric documentation in Application Insights.

При локальном запуске необходимо добавить APPINSIGHTS_INSTRUMENTATIONKEY параметр с ключом Application Insights в local.settings.jsв файле.When running locally, you must add the APPINSIGHTS_INSTRUMENTATIONKEY setting, with the Application Insights key, to the local.settings.json file.

Не вызывайте TrackRequest или StartOperation<RequestTelemetry>, ведь при этом будут отображаться повторные запросы на вызов функции.Don't call TrackRequest or StartOperation<RequestTelemetry> because you'll see duplicate requests for a function invocation. Среда выполнения Функций Azure автоматически отслеживает запросы.The Functions runtime automatically tracks requests.

Не указывайте telemetryClient.Context.Operation.Id.Don't set telemetryClient.Context.Operation.Id. Этот глобальный параметр может вызвать неправильную корреляцию при одновременном выполнении нескольких функций.This global setting causes incorrect correlation when many functions are running simultaneously. Вместо этого создайте экземпляр телеметрии (DependencyTelemetry, EventTelemetry) и измените его свойство Context.Instead, create a new telemetry instance (DependencyTelemetry, EventTelemetry) and modify its Context property. Затем передайте экземпляр телеметрии в соответствующий метод Track в TelemetryClient (TrackDependency(), TrackEvent(), TrackMetric()).Then pass in the telemetry instance to the corresponding Track method on TelemetryClient (TrackDependency(), TrackEvent(), TrackMetric()). Этот метод гарантирует правильность сведений о корреляции телеметрии для текущего вызова функции.This method ensures that the telemetry has the correct correlation details for the current function invocation.

Переменные средыEnvironment variables

Чтобы получить значение переменной среды или значение параметра приложения, используйте System.Environment.GetEnvironmentVariable, как показано в следующем примере кода.To get an environment variable or an app setting value, use System.Environment.GetEnvironmentVariable, as shown in the following code example:

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

    public static string GetEnvironmentVariable(string name)
    {
        return name + ": " +
            System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
    }
}

Параметры приложения могут считываться из переменных среды при разработке локально и при запуске в Azure.App settings can be read from environment variables both when developing locally and when running in Azure. При локальной разработке параметры приложения поступают из коллекции Values файла local.settings.json.When developing locally, app settings come from the Values collection in the local.settings.json file. Значение именованного параметра приложения GetEnvironmentVariable("<app setting name>") извлекается в локальной среде и среде Azure.In both environments, local and Azure, GetEnvironmentVariable("<app setting name>") retrieves the value of the named app setting. Например, при локальном запуске будет возвращено "Имя_сайта", если файл local.settings.json содержит { "Values": { "WEBSITE_SITE_NAME": "My Site Name" } }.For instance, when you're running locally, "My Site Name" would be returned if your local.settings.json file contains { "Values": { "WEBSITE_SITE_NAME": "My Site Name" } }.

Свойство System.Configuration.ConfigurationManager.AppSettings — альтернативный API-интерфейс для получения значения параметра приложения, но рекомендуется использовать GetEnvironmentVariable, как показано ниже.The System.Configuration.ConfigurationManager.AppSettings property is an alternative API for getting app setting values, but we recommend that you use GetEnvironmentVariable as shown here.

Привязка во время выполненияBinding at runtime

Для C# и других языков .NET можно использовать шаблон императивной привязки, которая отличается от декларативной привязки в атрибутах.In C# and other .NET languages, you can use an imperative binding pattern, as opposed to the declarative bindings in attributes. Императивную привязку удобно использовать, когда параметры привязки должны вычисляться не при проектировании, а во время выполнения.Imperative binding is useful when binding parameters need to be computed at runtime rather than design time. С использованием такого шаблона можно моментально выполнить привязку к поддерживаемым входным и выходным привязкам в коде функции.With this pattern, you can bind to supported input and output bindings on-the-fly in your function code.

Определите принудительную привязку следующим образом.Define an imperative binding as follows:

  • Не добавляйте атрибут в сигнатуру функции для нужных императивных привязок.Do not include an attribute in the function signature for your desired imperative bindings.

  • Передайте входной параметр Binder binder или IBinder binder.Pass in an input parameter Binder binder or IBinder binder.

  • Используйте следующий шаблон C# для привязки данных,Use the following C# pattern to perform the data binding.

    using (var output = await binder.BindAsync<T>(new BindingTypeAttribute(...)))
    {
        ...
    }
    

    где BindingTypeAttribute — атрибут .NET, определяющий пользовательскую привязку, а T — входной или выходной тип, поддерживаемый этим типом привязки.BindingTypeAttribute is the .NET attribute that defines your binding, and T is an input or output type that's supported by that binding type. T не может быть параметром типа out (например, out JObject).T cannot be an out parameter type (such as out JObject). Например, выходная привязка таблицы мобильных приложений поддерживает шесть выходных типов, но с императивной привязкой можно использовать только ICollector<T> или IAsyncCollector<T>.For example, the Mobile Apps table output binding supports six output types, but you can only use ICollector<T> or IAsyncCollector<T> with imperative binding.

Пример с одним атрибутомSingle attribute example

В следующем примере кода создается выходная привязка большого двоичного объекта службы хранилища с путем к большому двоичному объекту, определенному во время выполнения, а затем записывается строка в большой двоичный объект.The following example code creates a Storage blob output binding with blob path that's defined at run time, then writes a string to the 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!");
        };
    }
}

BlobAttribute определяет входную или выходную привязку большого двоичного объекта службы хранилища, а TextWriter представляет собой поддерживаемый тип выходной привязки.BlobAttribute defines the Storage blob input or output binding, and TextWriter is a supported output binding type.

Пример с несколькими атрибутамиMultiple attribute example

В предыдущем примере код получает параметр приложения для строки подключения основной учетной записи хранения приложения-функции (т. е. AzureWebJobsStorage).The preceding example gets the app setting for the function app's main Storage account connection string (which is AzureWebJobsStorage). Вы можете указать пользовательский параметр приложения, который следует использовать для учетной записи хранения. Для этого добавьте StorageAccountAttribute и передайте массив атрибутов в BindAsync<T>().You can specify a custom app setting to use for the Storage account by adding the StorageAccountAttribute and passing the attribute array into BindAsync<T>(). Используйте параметр Binder, а не IBinder.Use a Binder parameter, not IBinder. Пример:For example:

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

Триггеры и привязкиTriggers and bindings

В этой таблице показаны привязки, которые поддерживаются в двух основных версиях среды выполнения Функций Azure.This table shows the bindings that are supported in the major versions of the Azure Functions runtime:

ТипType 1.x1.x 2.x и выше12.x and higher1 ТриггерTrigger Входные данныеInput Выходные данныеOutput
Хранилище BLOB-объектовBlob storage
Azure Cosmos DBAzure Cosmos DB
Dapr3Dapr3
Сетка событийEvent Grid
Центры событийEvent Hubs
HTTP и веб-перехватчикиHTTP & webhooks
Центр Интернета вещейIoT Hub
Kafka2Kafka2
Мобильные приложенияMobile Apps
Центры уведомленийNotification Hubs
Хранилище очередейQueue storage
RabbitMQ2RabbitMQ2
SendGridSendGrid
Служебная шинаService Bus
SignalRSignalR
Хранилище таблицTable storage
ТаймерTimer
TwilioTwilio

1 Начиная со среды выполнения версии 2.х, все привязки, кроме HTTP и Timer, должны быть зарегистрированы.1 Starting with the version 2.x runtime, all bindings except HTTP and Timer must be registered. Ознакомьтесь с разделом Регистрация расширений привязки.See Register binding extensions.

2 Триггеры не поддерживаются в плане потребления.2 Triggers aren't supported in the Consumption plan. Требуются триггеры, управляемые средой выполнения.Requires runtime-driven triggers.

3 Поддерживается только в Kubernetes, IoT Edge и других автономных режимах.3 Supported only in Kubernetes, IoT Edge, and other self-hosted modes only.

Дальнейшие действияNext steps