Compartir a través de


Guía para ejecutar Azure Functions de C# en el modelo de trabajo aislado

En este artículo se presenta cómo trabajar con Azure Functions en .NET mediante el modelo de trabajo aislado. Este modelo permite que el proyecto apunte a versiones de .NET de manera independiente a otros componentes de tiempo de ejecución. Para obtener información sobre las versiones de .NET específicas admitidas, consulte versión admitida.

Utilice los siguientes vínculos para empezar de inmediato a crear funciones de modelo de trabajo aisladas de .NET.

Comenzar Conceptos Ejemplos
  • Opciones de hospedaje
  • Supervisión

Para obtener información sobre cómo implementar un proyecto de modelo de trabajo aislado en Azure, consulte Implementar en Azure Functions.

Ventajas del modelo de trabajo aislado

Puede ejecutar las funciones de biblioteca de clases de .NET en dos modos: en el mismo proceso que el runtime del host de Functions (in-process) o en un proceso de trabajo aislado. Cuando las funciones de .NET se ejecutan en un proceso de trabajo aislado, puede aprovechar las siguientes ventajas:

  • Menos conflictos: dado que las funciones se ejecutan en un proceso independiente, los ensamblados usados en la aplicación no entrarán en conflicto con la versión diferente de los mismos ensamblados que usa el proceso de host.
  • Control total del proceso: usted controla la puesta en marcha de la aplicación, lo que significa que puede administrar las configuraciones usadas y el middleware iniciado.
  • Inyección de dependencia estándar: Debido a que tienes pleno control del proceso, puedes utilizar los comportamientos actuales de .NET para la inyección de dependencias e incorporar middleware en tu aplicación de funciones.
  • Flexibilidad de versiones de .NET: Ejecutar fuera del proceso de host significa que las funciones se pueden ejecutar en versiones de .NET no admitidas de forma nativa por el runtime de Functions, incluido el .NET Framework.

Si tiene una aplicación de funciones de C# existente que se ejecuta en proceso, debe migrar la aplicación para aprovechar estas ventajas. Para obtener más información, consulte Migrar aplicaciones .NET del modelo en proceso al modelo de trabajador aislado.

Para obtener una comparación completa entre los dos modos, consulte Diferencias entre las funciones de Azure .NET que se ejecutan en el proceso y las que aíslan el proceso de trabajo.

Versiones compatibles

Las versiones del entorno de ejecución de Functions admiten versiones específicas de .NET. Para obtener más información sobre las versiones de Functions, consulte descripción general de las versiones del tiempo de ejecución de Azure Functions. La compatibilidad con versiones también depende de si las funciones se ejecutan en proceso o en proceso de trabajo aislado.

Nota:

Para aprender a cambiar la versión del runtime de Functions que usa la aplicación de funciones, consulte la sesión Visualización y actualización de la versión actual del entorno de ejecución.

En la tabla siguiente se muestra el nivel más alto de .NET o .NET Framework que se puede usar con una versión específica de Functions.

Versiones del entorno en tiempo de ejecución de Functions Modelo de trabajo aislado Modelo In-Process4
Funciones 4.x1 .NET 105
.NET 9.0
.NET 8.0
.NET Framework 4.82
.NET 8.0
Functions 1.x3 N/D .NET Framework 4.8

1 .NET 6 se admitía anteriormente en ambos modelos, pero alcanzó el fin del soporte oficial el 12 de noviembre de 2024. .NET 7 anteriormente era compatible con el modelo de trabajo aislado, pero alcanzó el fin del soporte oficial el 14 de mayo de 2024.

2 El proceso de compilación también requiere .NET SDK.

3 El soporte técnico finaliza para la versión 1.x del entorno de ejecución de Azure Functions el 14 de septiembre de 2026. Para obtener más información, consulte este anuncio de soporte técnico. Para seguir teniendo soporte completo, debería migrar sus aplicaciones a la versión 4.x.

4 El soporte técnico finaliza para el modelo In-Process el 10 de noviembre de 2026. Para obtener más información, consulte este anuncio de soporte técnico. Para seguir teniendo soporte técnico completo, debería migrar sus aplicaciones al modelo de trabajo aislado.

5 No se pueden ejecutar aplicaciones .NET 10 en Linux en el Plan de Consumo. Para ejecutarse en Linux, en su lugar debe usar el Plan de Consumo flexible. Para obtener instrucciones paso a paso sobre la migración, consulte Migración de aplicaciones de plan de consumo al plan de consumo flexible.

Para obtener las últimas noticias sobre las versiones de Azure Functions, incluida la eliminación de versiones secundarias anteriores específicas, supervise los anuncios de Azure App Service.

estructura del proyecto

Un proyecto .NET para Azure Functions que utiliza el modelo de trabajador aislado es básicamente un proyecto de aplicación de consola .NET que apunta a un entorno de ejecución .NET compatible. Los siguientes son los archivos básicos necesarios en cualquier proyecto aislado de .NET.

  • Archivo de proyecto de C# (.csproj) que define el proyecto y las dependencias.
  • Archivo program.cs que es el punto de entrada de la aplicación.
  • Cualquier archivo de código que defina las funciones.
  • host.json archivo que define la configuración compartida por funciones en el project.
  • local.settings.json archivo que define las variables de entorno usadas por el project cuando se ejecuta localmente en el equipo.

Para obtener ejemplos completos, consulte el proyecto de ejemplo .NET 8 y el proyecto de ejemplo .NET Framework 4.8.

Referencias de paquetes

Un proyecto .NET para Azure Functions que utiliza el modelo de trabajo aislado emplea un conjunto único de paquetes tanto para la funcionalidad básica como para las extensiones de enlace.

Paquetes base

Para ejecutar las funciones de .NET en un proceso de trabajo aislado, necesita los siguientes paquetes:

Las versiones mínimas de estos paquetes dependen de la versión de .NET de destino:

versión de .NET Microsoft.Azure.Functions.Worker Microsoft.Azure.Functions.Worker.Sdk
.NET 10 2.50.0 o posterior 2.0.5 o posterior
.NET 9 2.0.0 o posterior 2.0.0 o posterior
.NET 8 1.16.0 o posterior 1.11.0 o posterior
.NET Framework 1.16.0 o posterior 1.11.0 o posterior

Versión 2.x

Las versiones 2.x de los paquetes principales cambian los marcos admitidos y proporcionan compatibilidad con las nuevas API de .NET de estas versiones posteriores. Al actualizar a las versiones 2.x, tenga en cuenta los siguientes cambios:

  • A partir de la versión 2.0.0 de Microsoft. Azure. Functions.Worker.Sdk:
    • El SDK incluye configuraciones predeterminadas para compilaciones de contenedor delSDK.
    • El SDK incluye compatibilidad con dotnet run cuando se instala la Azure Functions Core Tools. En Windows, instale Core Tools a través de un mecanismo distinto de NPM.
  • A partir de la versión 2.0.0 de Microsoft. Azure. Functions.Worker:
    • Esta versión agrega compatibilidad con . Algunos ejemplos de esta guía incluyen pestañas para mostrar alternativas mediante . Estos ejemplos requieren las versiones 2.x.
    • La validación del ámbito del proveedor de servicios se incluye de forma predeterminada si se ejecuta en un entorno de desarrollo. Este comportamiento coincide con ASP.NET Core.
    • La opción está habilitada de forma predeterminada. La propiedad ahora está marcada como obsoleta.
    • La opción está habilitada de forma predeterminada. Con esta opción habilitada, las cargas de desencadenador que representan colecciones siempre incluyen entradas vacías. Por ejemplo, si se envía un mensaje sin cuerpo, todavía hay una entrada vacía en para los datos del activador. La inclusión de entradas vacías facilita la referencia cruzada con matrices de metadatos a las que también puede hacer referencia la función. Puede deshabilitar este comportamiento estableciendo en en la configuración del servicio de .
    • La clase cambia su nombre a . El cambio de nombre impide un error de llamada ambiguo al usar en una instancia de .
    • En el caso de aplicaciones que usan , el método ya no establece el código de estado en . En 1.x, este comportamiento invalida otros códigos de error que establezca.
  • Las versiones 2.x eliminan la compatibilidad con el TFM de .NET 5.

Paquetes de extensión

Dado que .NET funciones de proceso de trabajo aisladas usan diferentes tipos de enlace, requieren un conjunto único de paquetes de extensión de enlace.

Encontrará estos paquetes de extensión en Microsoft. Azure. Functions.Worker.Extensions.

Inicio y configuración

Al utilizar el modelo de trabajo aislado, tiene acceso al inicio de su aplicación de funciones, que normalmente se encuentra en Program.cs. El usuario es responsable de crear e iniciar su propia instancia de host. Por lo tanto, también tiene acceso directo a la canalización de configuración de tu aplicación. Con .NET proceso de trabajo aislado de Functions, puede agregar configuraciones mucho más fácilmente, insertar dependencias y ejecutar su propio middleware.

  • IHostApplicationBuilder
  • IHostBuilder

Para usar , la aplicación debe usar la versión 2.x o posterior de los paquetes principales.

El código siguiente muestra un ejemplo de una canalización IHostApplicationBuilder:

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

var builder = FunctionsApplication.CreateBuilder(args);

builder.Services
    .AddApplicationInsightsTelemetryWorkerService()
    .ConfigureFunctionsApplicationInsights();

builder.Logging.Services.Configure<LoggerFilterOptions>(options =>
    {
        // The Application Insights SDK adds a default logging filter that instructs ILogger to capture only Warning and more severe logs. Application Insights requires an explicit override.
        // Log levels can also be configured using appsettings.json. For more information, see https://learn.microsoft.com/azure/azure-monitor/app/worker-service#ilogger-logs
        LoggerFilterRule? defaultRule = options.Rules.FirstOrDefault(rule => rule.ProviderName
            == "Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider");
        if (defaultRule is not null)
        {
            options.Rules.Remove(defaultRule);
        }
    });

var host = builder.Build();

Antes de llamar a en , debe:

  • Si quiere usar ASP.NET Core integración, llame a builder.ConfigureFunctionsWebApplication().
  • Si va a escribir la aplicación con F#, es posible que tenga que registrar algunas extensiones de enlace. Consulte la documentación de configuración de la extensión Blobs, la extensión Tables y la extensión Cosmos DB cuando planee usar estas extensiones en una aplicación de F#.
  • Configure cualquier servicio o configuración de la aplicación que requiera su proyecto. Consulte Configuración para más detalles.
  • Si planea usar Application Insights, debe llamar a y en la propiedad del generador. Consulte Application Insights para obtener más información.

Si el proyecto tiene como destino .NET Framework 4.8, también debe agregar FunctionsDebugger.Enable(); antes de crear el HostBuilder. Debe ser la primera línea del método . Para obtener más información, consulte Debugging al dirigirse a .NET Framework.

El IHostApplicationBuilder se utiliza para compilar y devolver una instancia de completamente inicializada, que se ejecuta de forma asincrónica para iniciar la aplicación de funciones.

await host.RunAsync();

Configuración

El tipo de generador que usa determina cómo se configura la aplicación.

  • IHostApplicationBuilder
  • IHostBuilder

Use el método para agregar la configuración necesaria para que se ejecute la aplicación de funciones. El método incluye las funciones siguientes:

  • Conjunto predeterminado de convertidores.
  • Establezca el valor predeterminado de JsonSerializerOptions para omitir mayúsculas y minúsculas en los nombres de propiedad.
  • Integra con los registros de Azure Functions.
  • Middleware y características de enlace de salida.
  • Middleware de ejecución de función.
  • Soporte de gRPC predeterminado.
  • Se aplican otros valores predeterminados de Host.CreateDefaultBuilder().

Tiene acceso a la canalización del generador, por lo que puede establecer cualquier configuración específica de la aplicación durante la inicialización. Puede llamar métodos de extensión en la propiedad del generador para agregar cualquier origen de configuración que requiera el código. Para obtener más información sobre app configuration, vea Configuration en ASP.NET Core.

Estas configuraciones solo se aplican al código de trabajador que desarrolle. No influyen directamente en la configuración del host o los desencadenadores y enlaces de Functions. Para realizar cambios en el host de funciones o el desencadenador y la configuración de enlace, use el archivo host.json.

Nota:

Los orígenes de configuración personalizados no se pueden usar para la configuración de desencadenadores y enlaces. La configuración de desencadenador y enlace debe estar disponible para la plataforma de Functions y no solo para el código de la aplicación. Puede proporcionar esta configuración a través de la configuración de la aplicación, las referencias de Key Vault o las referencias de App Configuration.

Inserción de dependencia

El modelo de trabajo aislado usa mecanismos de .NET estándar para insertar servicios.

  • IHostApplicationBuilder
  • IHostBuilder

Cuando se usa un IHostApplicationBuilder, use su propiedad Services para acceder al IServiceCollection. En el ejemplo siguiente se inserta una dependencia del servicio singleton:

builder.Services.AddSingleton<IHttpResponderService, DefaultHttpResponderService>();

Este código requiere . Para obtener más información, consulte inyección de dependencias en ASP.NET Core.

Registro de clientes de Azure

Use la inserción de dependencias para interactuar con otros servicios de Azure. Puede insertar clientes desde el Azure SDK para .NET mediante el paquete Microsoft.Extensions.Azure. Después de instalar el paquete, registre los clientes usando AddAzureClients() en la colección de servicios en Program.cs. En el ejemplo siguiente se configura un cliente named para Azure Blobs:

  • IHostApplicationBuilder
  • IHostBuilder
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.Hosting;

var builder = FunctionsApplication.CreateBuilder(args);

builder.Services
    .AddAzureClients(clientBuilder =>
        {
            clientBuilder.AddBlobServiceClient(builder.Configuration.GetSection("MyStorageConnection"))
                .WithName("copierOutputBlob");
        });

builder.Build().Run();

En el ejemplo siguiente se muestra cómo puede usar este registro y los tipos de SDK para copiar el contenido del blob como una secuencia de un contenedor a otro mediante un cliente insertado:

using Microsoft.Extensions.Azure;
using Microsoft.Extensions.Logging;

namespace MyFunctionApp
{
    public class BlobCopier
    {
        private readonly ILogger<BlobCopier> _logger;
        private readonly BlobContainerClient _copyContainerClient;

        public BlobCopier(ILogger<BlobCopier> logger, IAzureClientFactory<BlobServiceClient> blobClientFactory)
        {
            _logger = logger;
            _copyContainerClient = blobClientFactory.CreateClient("copierOutputBlob").GetBlobContainerClient("samples-workitems-copy");
            _copyContainerClient.CreateIfNotExists();
        }

        [Function("BlobCopier")]
        public async Task Run([BlobTrigger("samples-workitems/{name}", Connection = "MyStorageConnection")] Stream myBlob, string name)
        {
            await _copyContainerClient.UploadBlobAsync(name, myBlob);
            _logger.LogInformation($"Blob {name} copied!");
        }

    }
}

En este ejemplo, también se obtiene a través de la inserción de dependencias, por lo que se registra automáticamente. Para más información sobre las opciones de configuración para el registro, consulte Registro.

Sugerencia

En el ejemplo se usa una cadena literal para el nombre del cliente tanto en como en la función. En su lugar, considere la posibilidad de usar una cadena de constante compartida definida en la clase de función. Por ejemplo, puede agregar y, después, hacer referencia a en ambas ubicaciones. De forma similar, puede definir el nombre de la sección de configuración con la función en lugar de en .

Software intermedio

El modelo de trabajo aislado también admite el registro de middleware, de nuevo mediante un modelo similar al que existe en ASP.NET. Este modelo proporciona la capacidad de insertar lógica en la canalización de invocación, y antes y después de que se ejecuten las funciones.

El método de extensión ConfigureFunctionsWorkerDefaults tiene una sobrecarga que le permite registrar su propio middleware, como se muestra en el ejemplo siguiente.

  • IHostApplicationBuilder
  • IHostBuilder
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var builder = FunctionsApplication.CreateBuilder(args);

// Register our custom middlewares with the worker
builder
    .UseMiddleware<ExceptionHandlingMiddleware>()
    .UseMiddleware<MyCustomMiddleware>()
    .UseWhen<StampHttpHeaderMiddleware>((context) =>
    {
        // We want to use this middleware only for http trigger invocations.
        return context.FunctionDefinition.InputBindings.Values
                        .First(a => a.Type.EndsWith("Trigger")).Type == "httpTrigger";
    });

builder.Build().Run();

El método de extensión registra un middleware que se ejecuta condicionalmente. Debe pasar un predicado que devuelva un valor booleano a este método. El middleware participa en la canalización de procesamiento de invocación cuando el predicado devuelve .

Los siguientes métodos de extensión en FunctionContext facilitan el trabajo con middleware en el modelo aislado.

Método Descripción
GetHttpRequestDataAsync Obtiene la instancia cuando la llamada la realiza un desencadenador HTTP. Este método devuelve una instancia de , que es útil cuando desea leer datos de mensajes, como encabezados de solicitud y cookies.
GetHttpResponseData Obtiene la instancia cuando la llamada la realiza un desencadenador HTTP.
GetInvocationResult Obtiene una instancia de , que representa el resultado de la ejecución de la función actual. Utilice la propiedad para obtener o establecer el valor según sea necesario.
GetOutputBindings Obtiene las entradas de enlace de salida para la ejecución de la función actual. Cada entrada del resultado de este método es de tipo . Puede utilizar la propiedad para obtener o establecer el valor según sea necesario.
BindInputAsync Enlaza un elemento de enlace de entrada para la instancia solicitada. Por ejemplo, use este método cuando tenga una función con una vinculación de entrada que necesita ser utilizada por su middleware.

En este ejemplo se muestra una implementación de middleware que lee la instancia y actualiza la instancia durante la ejecución de la función:

internal sealed class StampHttpHeaderMiddleware : IFunctionsWorkerMiddleware
{
    public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
    {
        var requestData = await context.GetHttpRequestDataAsync();

        string correlationId;
        if (requestData!.Headers.TryGetValues("x-correlationId", out var values))
        {
            correlationId = values.First();
        }
        else
        {
            correlationId = Guid.NewGuid().ToString();
        }

        await next(context);

        context.GetHttpResponseData()?.Headers.Add("x-correlationId", correlationId);
    }
}

Este middleware comprueba la presencia de un encabezado de solicitud específico (). Cuando el encabezado está presente, el middleware usa el valor de encabezado para marcar un encabezado de respuesta. De lo contrario, genera un nuevo valor GUID y usa ese valor para marcar el encabezado de respuesta.

Sugerencia

El patrón mostrado anteriormente de establecer encabezados de respuesta después de podría no funcionar de forma confiable en todos los escenarios. Este problema es especialmente cierto cuando se usa la integración con ASP.NET Core o en determinadas configuraciones en tiempo de ejecución en las que es posible que el flujo de respuesta ya se haya enviado. Para asegurarse de que los encabezados se establecen correctamente, considere la posibilidad de recuperar la respuesta de y establecer encabezados antes de que se devuelva la respuesta de la función, en lugar de intentar modificarlos en middleware una vez completada la ejecución de la función.

Para obtener un ejemplo más completo del uso de middleware personalizado en su aplicación de funciones, consulte el ejemplo de referencia de middleware personalizado.

Personalización de la serialización JSON

El modelo de trabajo aislado usa de forma predeterminada. Puede personalizar el comportamiento del serializador configurando los servicios como parte del archivo . En esta sección se cubre la serialización de uso general y no influye en la serialización JSON del desencadenador HTTP con la integración de ASP.NET Core, que debe configurar por separado.

  • IHostApplicationBuilder
  • IHostBuilder
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var builder = FunctionsApplication.CreateBuilder(args);

builder.ConfigureFunctionsWebApplication();

builder.Services.Configure<JsonSerializerOptions>(jsonSerializerOptions =>
    {
        jsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
        jsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
        jsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;

        // override the default value
        jsonSerializerOptions.PropertyNameCaseInsensitive = false;
    });

builder.Build().Run();

Para usar JSON.NET (Newtonsoft.Json) para la serialización, instale el paquete Microsoft.Azure.Core.NewtonsoftJson. A continuación, en el registro del servicio, vuelva a asignar la propiedad en la configuración de . En el ejemplo siguiente se muestra esta configuración mediante , pero también funciona para :

  • IHostApplicationBuilder
  • IHostBuilder
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var builder = FunctionsApplication.CreateBuilder(args);

builder.ConfigureFunctionsWebApplication();

builder.Services.Configure<WorkerOptions>(workerOptions =>
    {
        var settings = NewtonsoftJsonObjectSerializer.CreateJsonSerializerSettings();
        settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
        settings.NullValueHandling = NullValueHandling.Ignore;

        workerOptions.Serializer = new NewtonsoftJsonObjectSerializer(settings);
    });

builder.Build().Run();

Métodos reconocidos como funciones

Un método de función es un método público de una clase pública con un atributo aplicado al método y un atributo desencadenador aplicado a un parámetro de entrada, como en el ejemplo siguiente:

[Function(nameof(QueueInputOutputFunction))]
[QueueOutput("output-queue")]
public string[] QueueInputOutputFunction([QueueTrigger("input-queue")] Album myQueueItem, FunctionContext context)

El atributo desencadenador especifica el tipo de desencadenador y enlaza los datos de entrada a un parámetro del método. La función de ejemplo anterior se desencadena mediante un mensaje de cola y el mensaje de cola se pasa al método en el parámetro .

El atributo marca el método como punto de entrada de una función. El nombre debe ser único dentro de un project, comenzar con una letra y solo contener letras, números, _ y -, hasta 127 caracteres de longitud. Project plantillas suelen crear un método denominado Run, pero el nombre del método puede ser cualquier nombre de método de C# válido. Este método debe ser un miembro público de una clase pública. Por lo general, debe ser un método de instancia para que los servicios se puedan pasar a través de la inserción de dependencias.

Parámetros de función

Estos son algunos de los parámetros que puede incluir como parte de una firma de método de función:

  • Enlaces, que se marcan como tales mediante la decoración de los parámetros como atributos. La función debe contener exactamente un parámetro de desencadenador.
  • Un objeto de contexto de ejecución, que proporciona información sobre la invocación actual.
  • Un token de cancelación, que se usa para el apagado ordenado.

Contexto de ejecución

En el modelo de trabajo aislado, el proceso de trabajo pasa un objeto FunctionContext a los métodos de función. Este objeto permite obtener una instancia de ILogger para escribir en los registros llamando al método GetLogger y proporcionando una cadena categoryName. Puede usar este contexto para obtener un sin tener que usar la inserción de dependencias. Para obtener más información, vea Registro.

Tokens de cancelación

Una función puede aceptar un parámetro cancellationToken , que permite al sistema operativo notificar al código cuando la función está a punto de terminarse. Puede utilizar esta notificación para asegurarse de que la función no se termina inesperadamente en una forma que deje los datos en un estado incoherente.

Las funciones de .NET que se ejecutan en un proceso de trabajo aislado admiten tokens de cancelación. En el ejemplo siguiente se genera una excepción cuando se recibe una solicitud de cancelación:

[Function(nameof(ThrowOnCancellation))]
public async Task ThrowOnCancellation(
    [EventHubTrigger("sample-workitem-1", Connection = "EventHubConnection")] string[] messages,
    FunctionContext context,
    CancellationToken cancellationToken)
{
    _logger.LogInformation("C# EventHub {functionName} trigger function processing a request.", nameof(ThrowOnCancellation));

    foreach (var message in messages)
    {
        cancellationToken.ThrowIfCancellationRequested();
        await Task.Delay(6000); // task delay to simulate message processing
        _logger.LogInformation("Message '{msg}' was processed.", message);
    }
}

En el ejemplo siguiente se realizan acciones de limpieza cuando se recibe una solicitud de cancelación:

[Function(nameof(HandleCancellationCleanup))]
public async Task HandleCancellationCleanup(
    [EventHubTrigger("sample-workitem-2", Connection = "EventHubConnection")] string[] messages,
    FunctionContext context,
    CancellationToken cancellationToken)
{
    _logger.LogInformation("C# EventHub {functionName} trigger function processing a request.", nameof(HandleCancellationCleanup));

    foreach (var message in messages)
    {
        if (cancellationToken.IsCancellationRequested)
        {
            _logger.LogInformation("A cancellation token was received, taking precautionary actions.");
            // Take precautions like noting how far along you are with processing the batch
            _logger.LogInformation("Precautionary activities complete.");
            break;
        }

        await Task.Delay(6000); // task delay to simulate message processing
        _logger.LogInformation("Message '{msg}' was processed.", message);
    }
}

Escenarios que conducen a la cancelación

El token de cancelación se indica cuando se cancela la invocación de función. Varias razones podrían provocar una cancelación y esas razones varían en función del tipo de desencadenador que se use. Estos son algunos de los motivos habituales:

  • Desconexión del cliente: el cliente que invoca la función se desconecta. Este motivo es más probable para las funciones de desencadenador HTTP.
  • Reinicio de la aplicación de función: usted o la plataforma reinician (o detienen) la aplicación de función aproximadamente al mismo tiempo que se solicita una invocación. Se puede producir un reinicio debido a movimientos de instancias de trabajo, actualizaciones de instancias de trabajo o escalado.

Consideraciones sobre cancelación

  • Las invocaciones en curso durante un evento de reinicio se pueden reintentar en función de cómo se desencadenaron. Para obtener más información, consulte la documentación de reintento.

  • El host envía la invocación al trabajador incluso si el token de cancelación se cancela antes de que el host pueda enviar la solicitud de invocación al trabajador.

  • Si no desea que las invocaciones canceladas previamente se envíen al trabajador, agregue la propiedad al archivo de configuración para deshabilitar este comportamiento.

    En este ejemplo se muestra un archivo que usa esta propiedad:

    {
        "version": "2.0",
        "SendCanceledInvocationsToWorker": "false"
    }
    
  • Establecer en podría provocar una excepción con el siguiente registro:

    Se ha solicitado la cancelación. La solicitud de invocación con el identificador '{invocationId}' se cancela y no será enviada al trabajador.

    Esta excepción se produce cuando se cancela el token de cancelación (como resultado de uno de los eventos descritos anteriormente) antes de que el host envíe una solicitud de invocación entrante al trabajador. Esta excepción se puede omitir de forma segura y se espera cuando es .

La programación asíncrona

El trabajador aislado de .NET no establece un SynchronizationContext personalizado. Esto significa que es durante la ejecución de la función. Después de una await, las continuaciones se programan en el pool de subprocesos, que es el comportamiento estándar de .NET.

Dado que no hay que suprimir, el uso de en el código de función no tiene ningún efecto práctico. El proceso de trabajo aislado se ejecuta como un host genérico estándar de .NET (aplicación de consola), por lo que aquí se aplica el mismo comportamiento de async/await que cabría esperar en cualquier aplicación de consola o en ASP.NET Core. Esto también se aplica a las aplicaciones de trabajo aisladas de .NET Framework (net48), ya que el proceso de trabajo siempre es un ejecutable de consola mediante HostBuilder.

Nota:

Los orquestadores de Durable Functions tienen sus propias restricciones de subproceso. El subproceso de reproducción del orquestador debe ejecutar continuaciones, por lo que el uso en funciones o middleware del orquestador puede interferir con la ejecución de la orquestación. Para obtener más información, consulte las restricciones de código Durable Functions.

Enlaces

Defina enlaces mediante atributos en métodos, parámetros y tipos de valor devuelto. En su lugar, los enlaces se basan en cadenas, matrices y tipos serializables, como los objetos de clase anterior sin formato (POCO). Para algunas extensiones de enlace, también puede enlazar a tipos específicos de servicio definidos en los SDK de servicio.

Para los desencadenadores HTTP, consulte la sección Desencadenador HTTP.

Para obtener un conjunto completo de ejemplos de referencia que usan desencadenadores y enlaces con funciones de proceso de trabajo aisladas, consulte el ejemplo de referencia de extensiones de binding.

Enlaces de entrada

Una función puede tener cero o más enlaces de entrada que pasan datos a la función. Al igual que los desencadenadores, se definen los enlaces de entrada aplicando un atributo de enlace a un parámetro de entrada. Cuando se ejecuta la función, el entorno de ejecución intenta obtener los datos especificados en el enlace. Los datos que se solicitan a menudo dependen de la información proporcionada por el desencadenador a través de parámetros de enlace.

Enlaces de salida

Para escribir en un enlace de salida, se debe aplicar un atributo de enlace de salida al método de función. Este atributo define cómo escribir en el servicio enlazado. El valor de retorno del método se escribe en el vinculador de salida. Por ejemplo, en el ejemplo siguiente se escribe un valor de cadena en una cola de mensajes denominada mediante un enlace de salida:

[Function(nameof(QueueInputOutputFunction))]
[QueueOutput("output-queue")]
public string[] QueueInputOutputFunction([QueueTrigger("input-queue")] Album myQueueItem, FunctionContext context)
{
    // Use a string array to return more than one message.
    string[] messages = {
        $"Album name = {myQueueItem.Name}",
        $"Album songs = {myQueueItem.Songs}"};

    _logger.LogInformation("{msg1},{msg2}", messages[0], messages[1]);

    // Queue Output messages
    return messages;
}

Varios enlaces de salida

Los datos que se escriben en un enlace de salida siempre son el valor devuelto de la función. Si tiene que escribir en más de un enlace de salida, debe crear un tipo de valor devuelto personalizado. Este tipo de valor devuelto debe tener el atributo de enlace de salida aplicado a una o más propiedades de la clase. El ejemplo siguiente es una función desencadenada por HTTP que usa la integración de ASP.NET Core y escribe tanto en la respuesta HTTP como en una vinculación de salida de cola.

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

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

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

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

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

Al usar tipos de retorno personalizados para múltiples enlaces de salida con la integración de ASP.NET Core, debe agregar el atributo [HttpResult] a la propiedad que proporciona el resultado. El atributo /> SDK 1.17.3-preview2 o posterior junto con version 3.2.0 o posterior de la extensión HTTP y version 1.3.0 o posterior de la extensión ASP.NET Core.

Tipos de SDK

Para algunos tipos de enlace específicos del servicio, puede proporcionar datos de enlace mediante tipos de SDK de servicio y marcos de trabajo. Estos tipos ofrecen funcionalidades adicionales más allá de lo que puede proporcionar una cadena serializada o un objeto CLR sin formato (POCO). Para usar los tipos más recientes, actualice el project para usar versiones más recientes de las dependencias principales.

Dependencia Requisito de versión
Microsoft. Azure. Functions.Worker 1.18.0 o posterior
Microsoft. Azure. Functions.Worker.Sdk 1.13.0 o posterior

Al probar los tipos de SDK localmente en la máquina, también debe usar Azure Functions Core Tools, versión 4.0.5000 o posterior. Puede comprobar la versión actual mediante el comando .

Cada extensión de enlace también tiene su propio requisito de versión mínima, que se describe en los artículos de referencia sobre extensiones. Estas extensiones de enlace admiten actualmente tipos de SDK:

Extension Tipos Nivel de soporte
Azure Blob Storage BlobClient
BlobContainerClient
BlockBlobClient
PageBlobClient
AppendBlobClient
Desencadenador: GA
Entrada: disponibilidad general
Azure Cosmos DB CosmosClient
Database
Container
Entrada: disponibilidad general
Azure Event Grid CloudEvent
EventGridEvent
Desencadenador: GA
Azure Event Hubs EventData
EventHubProducerClient
Desencadenador: GA
Azure Queue Storage QueueClient
QueueMessage
Desencadenador: GA
Azure Service Bus ServiceBusClient
ServiceBusReceiver
ServiceBusSender
ServiceBusMessage
Desencadenador: GA
Azure Table Storage (almacenamiento en tablas de Azure) TableClient
TableEntity
Entrada: disponibilidad general

Consideraciones para los tipos de SDK:

  • Al usar expresiones de enlace que se basan en datos de desencadenador, no se pueden usar tipos de SDK para el propio desencadenador.
  • En escenarios de salida en los que puede usar un tipo de SDK, cree y trabaje con clientes del SDK directamente en lugar de usar un enlace de salida.
  • El desencadenador de Azure Cosmos DB usa la fuente de cambios Azure Cosmos DB y expone elementos de fuente de cambios como tipos serializables json. Como resultado, los tipos de SDK no se admiten para este desencadenador.

Desencadenador HTTP

Los desencadenadores HTTP permiten invocar una función mediante una solicitud HTTP. Puede usar dos enfoques diferentes:

  • Un modelo de integración ASP.NET Core que usa conceptos conocidos para ASP.NET Core desarrolladores
  • Un modelo integrado, que no requiere dependencias adicionales y usa tipos personalizados para solicitudes y respuestas HTTP. Este enfoque se mantiene por motivos de compatibilidad con versiones anteriores de aplicaciones de trabajadores aislados de .NET.

integración de ASP.NET Core

En esta sección se muestra cómo trabajar con los objetos de solicitud y respuesta HTTP subyacentes mediante tipos de ASP.NET Core, incluidos HttpRequest, HttpResponse y IActionResult. Este modelo no está disponible para apps que tienen como destino .NET Framework, que en su lugar debe usar el modelo built-in.

Nota:

Este modelo no expone todas las características de ASP.NET Core. En concreto, no proporciona acceso a las funcionalidades de canalización y enrutamiento de middleware de ASP.NET Core. ASP.NET Core integración requiere que use paquetes actualizados.

Para habilitar la integración de ASP.NET Core para HTTP:

  1. Agregue una referencia en el project al Microsoft.Azure. Functions.Worker.Extensions.Http.AspNetCore paquete, versión 1.0.0 o posterior.

  2. Actualice el project para usar estas versiones de paquete específicas:

  3. En el archivo , actualice la configuración del generador de hosts para que llame a . Este método reemplaza si de lo contrario usarías ese método. En el ejemplo siguiente se muestra una configuración mínima sin otras personalizaciones:

    • IHostBuilder
    • IHostApplicationBuilder

    Nota:

    La aplicación debe hacer referencia a la versión 2.0.0 o posterior de Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore para usar la integración de ASP.NET Core con IHostApplicationBuilder.

    using Microsoft.Azure.Functions.Worker.Builder;
    using Microsoft.Extensions.Hosting;
    
    var builder = FunctionsApplication.CreateBuilder(args);
    
    builder.ConfigureFunctionsWebApplication();    
    
    builder.Build().Run();
    
  4. Actualice las funciones desencadenadas por HTTP existentes para usar los tipos de ASP.NET Core. Este ejemplo muestra el estándar y un usado para una función sencilla de "hola, mundo":

    [Function("HttpFunction")]
    public IActionResult Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req)
    {
        return new OkObjectResult($"Welcome to Azure Functions, {req.Query["name"]}!");
    }
    

Serialización JSON con integración de ASP.NET Core

ASP.NET Core tiene su propia capa de serialización y no se ve afectada por la configuración de serialización general. Para personalizar el comportamiento de serialización usado para los desencadenadores HTTP, debe incluir una llamada como parte del registro del servicio. Se puede usar el IMvcBuilder devuelto para modificar la configuración de serialización JSON de ASP.NET Core.

Puede seguir usando HttpRequestData y HttpResponseData mientras usa la integración de ASP.NET, aunque para la mayoría de las aplicaciones, es mejor usar HttpRequest y IActionResult. El uso de HttpRequestData/HttpResponseData no invoca la capa de serialización de ASP.NET Core y, en su lugar, se basa en la configuración general de serialización del trabajador para la aplicación. Sin embargo, cuando se habilita la integración de ASP.NET Core, es posible que tenga que agregar configuraciones. El comportamiento predeterminado de ASP.NET Core es no permitir la E/S sincrónica. Para usar un serializador personalizado que no admite E/S asincrónica, como , debe habilitar la E/S sincrónica para la aplicación mediante la configuración de .

En el ejemplo siguiente se muestra cómo configurar json.NET (Newtonsoft.Json) y el paquete NuGet Microsoft.AspNetCore.Mvc.NewtonsoftJson para la serialización mediante este enfoque:

  • IHostApplicationBuilder
  • IHostBuilder
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var builder = FunctionsApplication.CreateBuilder(args);

builder.ConfigureFunctionsWebApplication();

builder.Services
    .AddApplicationInsightsTelemetryWorkerService()
    .ConfigureFunctionsApplicationInsights();

builder.Services.AddMvc().AddNewtonsoftJson();

// Only needed if using HttpRequestData/HttpResponseData and a serializer that doesn't support asynchronous IO
// builder.Services.Configure<KestrelServerOptions>(options => options.AllowSynchronousIO = true);

builder.Build().Run();

Modelos HTTP integrados

En el modelo integrado, el sistema traduce el mensaje de solicitud HTTP entrante en un objeto HttpRequestData que pasa a la función. Este objeto proporciona datos de la solicitud, incluidos , , , y un mensaje opcional . Este objeto representa la solicitud HTTP, pero no está conectada directamente al agente de escucha HTTP subyacente o al mensaje recibido.

Importante

Si usa , el cuerpo de la solicitud HTTP no puede ser una secuencia. Por ejemplo, si la solicitud tiene el encabezado y ningún encabezado, la propiedad del objeto será una secuencia nula. Si necesita trabajar con solicitudes HTTP de streaming, considere la posibilidad de usar el modelo de integración de ASP.NET Core en su lugar.

Del mismo modo, la función devuelve un objeto HttpResponseData, que proporciona datos usados para crear la respuesta HTTP, incluido message StatusCode, Headers y, opcionalmente, un mensaje Body.

El siguiente ejemplo muestra el uso de y :

[Function(nameof(HttpFunction))]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequestData req,
    FunctionContext executionContext)
{
    var logger = executionContext.GetLogger(nameof(HttpFunction));
    logger.LogInformation("message logged");

    var response = req.CreateResponse(HttpStatusCode.OK);
    response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
    response.WriteString("Welcome to .NET isolated worker !!");

    return response;
}

Registro

Puede escribir en los registros mediante una instancia o . Puede obtener el registrador a través de la inserción de dependencias de un o de un ILoggerFactory:

public class MyFunction {
    
    private readonly ILogger<MyFunction> _logger;
    
    public MyFunction(ILogger<MyFunction> logger) {
        _logger = logger;
    }
    
    [Function(nameof(MyFunction))]
    public void Run([BlobTrigger("samples-workitems/{name}", Connection = "")] string myBlob, string name)
    {
        _logger.LogInformation($"C# Blob trigger function Processed blob\n Name: {name} \n Data: {myBlob}");
    }

}

Nota:

Al insertar un en el constructor de clase, como en el ejemplo anterior, la categoría de registro se establece automáticamente en el nombre completo de esa clase, como . Estos nombres de categoría contienen caracteres (punto). Al hospedar la aplicación de funciones en Linux, no puede usar variables de entorno para invalidar los niveles de registro de las categorías que contienen períodos. Para solucionar esta limitación, puede configurar los niveles de registro en el código o en un archivo .

También puedes obtener el registrador de un objeto FunctionContext que se pasa a tu función. Llame al método GetLogger<T> o GetLogger, pasando un valor de cadena que es el nombre de la categoría en la que se escriben los registros. La categoría suele ser el nombre de la función específica desde la que se escriben los registros. Para obtener más información sobre las categorías, consulte el artículo de supervisión.

Use los métodos de y para escribir varios niveles de registro, como o . Para obtener más información sobre los niveles de registro, consulte el artículo de supervisión. Puede personalizar los niveles de registro de los componentes agregados al código registrando filtros:

  • IHostApplicationBuilder
  • IHostBuilder
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

var builder = FunctionsApplication.CreateBuilder(args);

builder.ConfigureFunctionsWebApplication();

// Registers IHttpClientFactory.
// By default this sends a lot of Information-level logs.
builder.Services.AddHttpClient();

// Disable IHttpClientFactory Informational logs.
// Note -- you can also remove the handler that does the logging: https://github.com/aspnet/HttpClientFactory/issues/196#issuecomment-432755765 
builder.Logging.AddFilter("System.Net.Http.HttpClient", LogLevel.Warning);
    
builder.Build().Run();

Como parte de la configuración de la aplicación en , también puede definir el comportamiento de cómo se muestran los errores en los registros. El comportamiento predeterminado depende del tipo de generador que esté usando.

  • IHostApplicationBuilder
  • IHostBuilder

Cuando usas una , las excepciones lanzadas por tu código fluyen a través del sistema sin cambios. No necesita ninguna otra configuración.

Application Insights

Puede configurar la aplicación de proceso aislada para enviar registros directamente a Application Insights. Esta configuración reemplaza el comportamiento predeterminado de la retransmisión de registros a través del host. A menos que use Aspire, configure la integración directa de Application Insights porque le proporciona control sobre cómo se emiten esos registros.

La integración de Application Insights no está habilitada de forma predeterminada en todas las experiencias de configuración. Algunas plantillas crean proyectos de Funciones con los paquetes necesarios y el código de inicio comentados. Si desea usar la integración de Application Insights, descomente estas líneas en Program.cs y en el archivo del proyecto .csproj. Las instrucciones del resto de esta sección también describen cómo habilitar la integración.

Si el proyecto forma parte de una orquestación Aspire, utiliza OpenTelemetry para la supervisión. No habilite la integración directa de Application Insights en proyectos aspire. En su lugar, configure el exportador de OpenTelemetry de Azure Monitor como parte de los valores predeterminados de servicio del proyecto . Si functions project usa la integración de Application Insights en un contexto de Aspire, la aplicación produce errores al iniciarse.

Instalar paquetes

Para escribir registros directamente en Application Insights desde el código, agregue referencias a estos paquetes en el project:

Ejecute los siguientes comandos para agregar estas referencias a su proyecto:

dotnet add package Microsoft.ApplicationInsights.WorkerService
dotnet add package Microsoft.Azure.Functions.Worker.ApplicationInsights

Configuración del inicio

Después de instalar los paquetes, llame a y durante la configuración del servicio en el archivo , como se muestra en el ejemplo siguiente.

  • IHostApplicationBuilder
  • IHostBuilder
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
    
var builder = FunctionsApplication.CreateBuilder(args);

builder.Services
    .AddApplicationInsightsTelemetryWorkerService()
    .ConfigureFunctionsApplicationInsights();

builder.Build().Run();

La llamada a agrega un que escucha a un definido por Functions. En este módulo se crea la telemetría de dependencia necesaria para admitir el seguimiento distribuido. Para obtener más información sobre AddApplicationInsightsTelemetryWorkerService() y cómo usarlo, consulte Application Insights for Worker Service applications.

Administración de niveles de registro

Importante

El host de Functions y el trabajador de proceso aislado tienen configuraciones independientes para los niveles de registro. Cualquier configuración de Application Insights en host.json no afecta el registro del trabajador, y de manera similar, la configuración en el código de su trabajador no afecta el registro del host. Aplique cambios en ambos lugares si el escenario requiere personalización en ambas capas.

El resto de la aplicación sigue funcionando con y . Pero de manera predeterminada, el SDK de Application Insights agrega un filtro de registro que indica al registrador que capture solo advertencias y registros más graves. Puede configurar los niveles de registro en el proceso de trabajo aislado de una de estas maneras:

Método de configuración Ventajas
En tu código Promueve una separación más clara entre las configuraciones del lado host y del lado de trabajo.
Usar Resulta útil cuando desea establecer diferentes niveles de registro para diferentes categorías sin tener que modificar el código.
  • Basado en código
  • Configuración

Para deshabilitar el comportamiento predeterminado y capturar todos los niveles de registro, quite la regla de filtro como parte de la configuración del servicio:

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

var builder = FunctionsApplication.CreateBuilder(args);

builder.Services
    .AddApplicationInsightsTelemetryWorkerService()
    .ConfigureFunctionsApplicationInsights();

builder.Logging.Services.Configure<LoggerFilterOptions>(options =>
    {
        LoggerFilterRule? defaultRule = options.Rules.FirstOrDefault(rule => rule.ProviderName
            == "Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider");
        if (defaultRule is not null)
        {
            options.Rules.Remove(defaultRule);
        }
    });

builder.Build().Run();

Para obtener más información sobre cómo configurar el registro, consulte Logging in .NET and Application Insights for Worker Service applications.

Optimizaciones de rendimiento

En esta sección se describen las opciones que puede habilitar para mejorar el rendimiento en torno al arranque de acceso esporádico.

En general, la aplicación debe usar las versiones más recientes de sus dependencias principales. Como mínimo, actualice el project de la manera siguiente:

  1. Actualice Microsoft. Azure. Functions.Worker a la versión 1.19.0 o posterior.
  2. Actualice Microsoft. Azure. Functions.Worker.Sdk a la versión 1.16.4 o posterior.
  3. Agregue una referencia de marco a Microsoft.AspNetCore.App, a menos que la aplicación tenga como destino .NET Framework.

En el fragmento de código siguiente se muestra esta configuración en el contexto de un archivo project:

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.21.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.16.4" />
  </ItemGroup>

Marcadores de posición

Los marcadores de posición son una funcionalidad de plataforma que mejora el arranque en frío para las aplicaciones destinadas a .NET 6 o posterior. Para usar esta optimización, debe habilitar explícitamente los marcadores de posición siguiendo estos pasos:

  1. Actualice la configuración de project para usar las versiones de dependencia más recientes, como se detalla en la sección anterior.

  2. Establezca la configuración de la aplicación en . Utilice el comando az functionapp config appsettings set.

    az functionapp config appsettings set -g <groupName> -n <appName> --settings 'WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED=1'
    

    En este ejemplo, sustituya por el nombre del grupo de recursos y reemplace por el nombre de su aplicación de funciones.

  3. Asegúrese de que la propiedad netFrameworkVersion de la aplicación de función coincida con la plataforma de destino del proyecto, que debe ser .NET 6 o posterior. Utilice el comando az functionapp config set.

    az functionapp config set -g <groupName> -n <appName> --net-framework-version <framework>
    

    En este ejemplo, reemplace también <framework> por la cadena de versión adecuada, como v8.0, según la versión de .NET de destino.

  4. Asegúrese de que la aplicación de funciones está configurada para usar un proceso de 64 bits. Utilice el comando az functionapp config set

    az functionapp config set -g <groupName> -n <appName> --use-32bit-worker-process false
    

Importante

Cuando configure el en , debe establecer correctamente todas las demás configuraciones de la aplicación de funciones. De lo contrario, es posible que la aplicación de funciones no se inicie.

Ejecutor optimizado

El ejecutor de funciones es un componente de la plataforma que hace que se ejecuten invocaciones. Una versión optimizada de este componente está habilitada de forma predeterminada a partir de la versión 1.16.2 del SDK. No es necesario efectuar ninguna otra configuración.

ReadyToRun

La aplicación de funciones se puede compilar como archivos binarios de ReadyToRun. ReadyToRun es una forma de compilación Ahead Of Time que puede mejorar el rendimiento de inicio para ayudar a reducir el impacto del inicio en frío cuando se ejecuta en un plan de consumo. ReadyToRun está disponible en .NET 6 y versiones posteriores y requiere version 4.0 o posterior del entorno de ejecución de Azure Functions.

ReadyToRun requiere que compile el proyecto contra la arquitectura del tiempo de ejecución de la aplicación de hospedaje. Cuando estas arquitecturas no están alineadas, la aplicación encuentra un error al iniciarse. Seleccione su identificador de tiempo de ejecución en esta tabla:

Sistema operativo La aplicación es de 32 bits1 Identificador en tiempo de ejecución
Windows Cierto win-x86
Windows Falso win-x64
Linux Cierto N/D (no compatible).
Linux Falso linux-x64

1 Solo las aplicaciones de 64 bits son aptas para otras optimizaciones de rendimiento.

Para comprobar si el Windows app es de 32 o 64 bits, ejecute el siguiente comando de la CLI, sustituyendo <group_name> por el nombre del grupo de recursos y <app_name> con el nombre de la aplicación. Una salida de "true" indica que la aplicación es de 32 bits y "false" indica que es de 64 bits.

 az functionapp config show -g <group_name> -n <app_name> --query "use32BitWorkerProcess"

Puede cambiar la aplicación a 64 bits con el siguiente comando mediante las mismas sustituciones:

az functionapp config set -g <group_name> -n <app_name> --use-32bit-worker-process false`

Para compilar su proyecto como ReadyToRun, actualice el archivo de proyecto agregando los elementos <PublishReadyToRun> y <RuntimeIdentifier>. El ejemplo siguiente muestra una configuración para publicar en una aplicación de funciones de Windows de 64 bits.

<PropertyGroup>
  <TargetFramework>net8.0</TargetFramework>
  <AzureFunctionsVersion>v4</AzureFunctionsVersion>
  <RuntimeIdentifier>win-x64</RuntimeIdentifier>
  <PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>

Si no desea establecer el <RuntimeIdentifier> como parte del archivo de proyecto, también puede configurar este valor como parte del proceso de publicación. Por ejemplo, con una aplicación de funciones de Windows de 64 bits, el comando .NET CLI es:

dotnet publish --runtime win-x64

En Visual Studio, establezca la opción Entorno de Ejecución Objetivo en el perfil de publicación al identificador correcto de tiempo de ejecución. Cuando se establece en el valor predeterminado de Portable, no se usa ReadyToRun.

Desplegar en Azure Functions

Cuando se despliega el proyecto de código de función en Azure, debe ejecutarse en una aplicación de funciones o en un entorno de Linux. Debe crear la aplicación de funciones y otros recursos necesarios Azure antes de implementar el código.

También puede implementar la aplicación de funciones en un contenedor de Linux. Para obtener más información, consulte Working with containers and Azure Functions.

Creación de recursos de Azure

Puede crear la aplicación de funciones y otros recursos necesarios en Azure mediante uno de estos métodos:

  • Visual Studio: Visual Studio puede crear recursos automáticamente durante el proceso de publicación de código.
  • Visual Studio Code: Visual Studio Code puede conectarse a la suscripción, crear los recursos necesarios para la aplicación y, a continuación, publicar el código.
  • Azure CLI: use el Azure CLI para crear los recursos necesarios en Azure.
  • Azure PowerShell: use Azure PowerShell para crear los recursos necesarios en Azure.
  • Plantillas de implementación: use plantillas de ARM y archivos de Bicep para automatizar la implementación de los recursos necesarios para Azure. Asegúrese de que su plantilla incluye cualquier configuración necesaria.
  • Azure portal: cree los recursos necesarios en el Azure portal.

Publicación de la aplicación

Después de crear la función y otros recursos necesarios en Azure, implemente el proyecto de código en Azure mediante uno de estos métodos:

  • Visual Studio: implementación manual sencilla durante el desarrollo.
  • Visual Studio Code: implementación manual sencilla durante el desarrollo.
  • Azure Functions Core Tools: Implementar archivo de proyecto desde la línea de comandos.
  • Implementación continua: útil para el mantenimiento continuo, con frecuencia en un espacio de ensayo.
  • Plantillas de implementación: Puede usar plantillas ARM o archivos Bicep para automatizar la implementación de paquetes.

Para obtener más información, consulte Tecnologías de implementación en Azure Functions.

Carga de implementación

Muchos de los métodos de implementación usan un archivo ZIP. Si crea el archivo ZIP usted mismo, debe seguir la estructura que se describe en esta sección. Si no es así, la aplicación podría experimentar errores al iniciarse.

La carga de implementación debe coincidir con la salida de un comando , aunque sin la carpeta principal envolvente. El archivo ZIP debe realizarse a partir de los siguientes archivos:

  • .azurefunctions/
  • extensions.json
  • functions.metadata
  • host.json
  • worker.config.json
  • El archivo ejecutable de tu proyecto (una aplicación de consola)
  • Otros archivos auxiliares y directorios del mismo nivel a ese ejecutable

El proceso de compilación genera estos archivos y no debe editarlos directamente.

Sugerencia

Puede usar el comando en Core Tools para generar correctamente un archivo ZIP para la implementación. La compatibilidad con está actualmente en versión preliminar.

Al preparar un archivo ZIP para la implementación, comprima solo el contenido del directorio de salida, no el propio directorio envolvente. Cuando el archivo se extrae en el directorio de trabajo actual, los archivos enumerados anteriormente deben estar visibles inmediatamente.

Requisitos de implementación

Para ejecutar .NET funciones en el modelo de trabajo aislado en Azure, debe cumplir algunos requisitos. Los requisitos dependen del sistema operativo:

  • Windows
  • Linux
  • Establezca FUNCTIONS_WORKER_RUNTIME en .
  • Establezca netFrameworkVersion en la versión deseada.

Al crear la aplicación de funciones en Azure con los métodos de la sección anterior, se agregan automáticamente estas opciones de configuración necesarias. Cuando cree estos recursos utilizando plantillas ARM o archivos Bicep para la automatización, debe asegurarse de establecerlos en la plantilla.

Aspirar

Aspire es una pila con opiniones que simplifica el desarrollo de aplicaciones distribuidas en la nube. Puede inscribir proyectos de modelo de trabajo aislados en orquestaciones Aspire 13. Consulte Azure Functions with Aspire para obtener más información.

Depuración

Cuando se ejecuta localmente mediante Visual Studio o Visual Studio Code, puedes depurar tu proyecto de trabajador aislado de .NET de manera normal. Sin embargo, hay dos escenarios de depuración que no funcionan según lo previsto.

Depuración remota mediante Visual Studio

Dado que la aplicación de proceso de trabajo aislado se ejecuta fuera del entorno de ejecución de Functions, debe asociar el depurador remoto a un proceso independiente. Para obtener más información sobre la depuración mediante Visual Studio, consulte Depuración Remota.

Depuración al trabajar con .NET Framework

Si el proyecto aislado apunta a .NET Framework 4.8, debe realizar pasos manuales para habilitar la depuración. Estos pasos no son necesarios si se usa otra plataforma de destino.

La aplicación debe empezar con una llamada a como primera operación. Esto ocurre en el método antes de inicializar un HostBuilder. El archivo debe tener un aspecto similar al siguiente:

  • IHostApplicationBuilder
  • IHostBuilder
using System;
using System.Diagnostics;
using Microsoft.Extensions.Hosting;
using Microsoft.Azure.Functions.Worker;
using NetFxWorker;

namespace MyDotnetFrameworkProject
{
    internal class Program
    {
        static void Main(string[] args)
        {
            FunctionsDebugger.Enable();

            var host = FunctionsApplication
                .CreateBuilder(args)
                .Build();

            host.Run();
        }
    }
}

A continuación, debe conectar manualmente al proceso mediante un depurador del .NET Framework. Visual Studio aún no realiza esto automáticamente para las aplicaciones de .NET Framework con proceso de trabajo aislado, y se debe evitar la operación "Iniciar depuración".

En el directorio project (o en su directorio de salida de compilación), ejecute:

func host start --dotnet-isolated-debug

Esto inicia el trabajo y el proceso se detiene con el siguiente mensaje:

Azure Functions .NET Worker (PID: <process id>) initialized in debug mode. Waiting for debugger to attach...

Donde es el id. del proceso de trabajo. Ahora puede usar Visual Studio para asociarse manualmente al proceso. Para instrucciones sobre esta operación, consulte Asociación con un proceso en ejecución.

Una vez asociado el depurador, la ejecución del proceso se reanuda y podrá depurar.

Versiones preliminares de .NET

Antes de una versión disponible con carácter general, una versión de .NET podría publicarse en un estado Preview o Go-live. Consulte la .NET Directiva de soporte técnico oficial para obtener más información sobre estos estados.

Aunque puede ser posible apuntar a una versión determinada desde un proyecto local de Functions, es posible que las aplicaciones de funciones hospedadas en Azure no tengan esa versión disponible. Azure Functions solo se pueden usar con versiones de prueba o lanzamiento en producción que se mencionan en esta sección.

Azure Functions no funciona actualmente con ninguna versión preliminar o "Go-live" .NET. Consulte Versiones admitidas para obtener una lista de versiones disponibles con carácter general que puede usar.

Uso de una versión preliminar del SDK de .NET

Para usar Azure Functions con una versión preliminar de .NET, debe actualizar el proyecto de la siguiente manera:

  1. Instalación de la versión pertinente del SDK de .NET en el desarrollo
  2. Cambiando la configuración en el archivo

Al implementar una aplicación de funciones en Azure, también debe asegurarse de que el framework esté disponible para la aplicación. Durante el período de versión preliminar, es posible que algunas herramientas y experiencias no presenten la nueva versión preliminar como opción. Si no ve la versión preliminar incluida en el Azure portal, por ejemplo, puede usar la API REST, los archivos de Bicep o el Azure CLI para configurar la versión manualmente.

  • Windows
  • Linux

En el caso de las aplicaciones hospedadas en Windows, use el siguiente comando Azure CLI. Reemplace por el nombre del grupo de recursos y por el nombre de la aplicación de funciones. Reemplace por la cadena de versión adecuada, como .

az functionapp config set -g <groupName> -n <appName> --net-framework-version <framework>

Consideraciones para usar versiones preliminares de .NET

Tenga en cuenta estas consideraciones al usar Functions con versiones preliminares de .NET:

  • Al crear las funciones en Visual Studio, debe usar Visual Studio Insiders, que admite la creación de proyectos de Azure Functions con SDK de versión preliminar de .NET.

  • Asegúrese de que tiene las últimas herramientas y plantillas de Functions. Para actualizar las herramientas:

    1. Vaya a Tools>Options, elija Azure Functions en Projects and Solutions>More Settings.
    2. Seleccione Buscar actualizaciones e instale las actualizaciones según se le solicite.
  • Durante un período de versión preliminar, el entorno de desarrollo puede tener una versión más reciente de la .NET versión preliminar que el servicio hospedado. Esto puede hacer que se produzca un error en la aplicación de funciones cuando se implementa. Para solucionar esto, puede especificar la versión del SDK que se va a usar en .

    1. Ejecute el comando y anote la versión preliminar que está usando actualmente durante el desarrollo local.
    2. Ejecute el comando , donde es la versión que usa localmente. Por ejemplo, dotnet new globaljson --sdk-version dotnet-sdk-10.0.100-preview.5.25277.114 --force hace que el sistema use el SDK de .NET 10 Preview 5 al compilar el project.

Nota:

Debido a la carga Just-In-Time de marcos de versión preliminar, las aplicaciones de funciones que se ejecutan en Windows pueden experimentar tiempos de inicio de acceso esporádico aumentados en comparación con las versiones anteriores de disponibilidad general.

Pasos siguientes

Integración con Aspire