Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este artigo apresenta o trabalho com o Azure Functions no .NET usando o modelo de trabalho isolado. Esse modelo permite que o projeto direcione versões do .NET independentemente de outros componentes de runtime. Para obter informações sobre versões específicas do .NET com suporte, confira versão com suporte.
Use os links a seguir para começar imediatamente a criar funções de modelo de trabalho isoladas do .NET.
| Introdução | Conceitos | Exemplos |
|---|---|---|
Para saber mais sobre como implantar um projeto de modelo de trabalho isolado no Azure, consulte Implantar no Azure Functions.
Benefícios do modelo de trabalho isolado
Você pode executar suas funções de biblioteca de classes do .NET em dois modos: no mesmo processo que o runtime do host do Functions (em processo) ou em um processo de trabalho isolado. Quando suas funções .NET são executadas em um processo de trabalho isolado, você pode aproveitar os seguintes benefícios:
- Menos conflitos: como suas funções são executadas em um processo separado, os assemblies usados em seu aplicativo não entram em conflito com versões diferentes dos mesmos assemblies usados pelo processo de host.
- Controle total do processo: você controla a inicialização do aplicativo, o que significa que você pode gerenciar as configurações usadas e o middleware iniciado.
- Injeção de dependência padrão: como você tem controle total do processo, você pode usar os comportamentos atuais do .NET para injeção de dependência e incorporar middleware em seu aplicativo de funções.
- Flexibilidade de versão do .NET: em execução fora do processo de host significa que suas funções podem ser executadas em versões do .NET sem suporte nativo pelo runtime do Functions, incluindo o .NET Framework.
Se você tiver um aplicativo de funções C# existente que é executado em processo, precisará migrar seu aplicativo para aproveitar esses benefícios. Para obter mais informações, confira Migrar aplicativos .NET do modelo em processo para o modelo de trabalho isolado.
Para obter uma comparação abrangente entre os dois modos, confira Diferenças entre o modelo de processo de trabalho isolado e o modelo em processo do .NET Azure Functions.
Versões com suporte
As versões do runtime do Functions aceitam versões específicas do .NET. Saiba mais sobre as versões do Functions, confira Visão geral de versões do Azure Functions runtime. O suporte a uma versão depende de suas funções serem executadas em processo ou no processo de trabalho isolado.
Observação
Para saber como alterar a versão de runtime do Functions usada pelo aplicativo de funções, confira Exibir e atualizar a versão de runtime atual.
A tabela a seguir mostra o nível mais alto do .NET ou .NET Framework que pode ser usado com uma versão específica do Functions.
| Versão do runtime do Functions | Modelo de trabalho isolado | Modelo em processo4 |
|---|---|---|
| Funções 4.x1 | .NET 105 .NET 9.0 .NET 8.0 .NET Framework 4.82 |
.NET 8.0 |
| Funções 1.x3 | n/d | .NET Framework 4.8 |
1 Anteriormente, o .NET 6 tinha suporte nos dois modelos, mas chegou ao fim do suporte oficial em 12 de novembro de 2024. O .NET 7 era compatível com o modelo de trabalho isolado, mas chegou ao fim do suporte oficial em 14 de maio de 2024.
2 O processo de build também exige o SDK do .NET.
3 O suporte para a versão 1.x do runtime do Azure Functions termina em 14 de setembro de 2026. Para obter mais informações, confira este comunicado de suporte. Para obter suporte completo contínuo, você deve migrar seus aplicativos para a versão 4.x.
4 O suporte para o modelo em processo termina em 10 de novembro de 2026. Para obter mais informações, confira este comunicado de suporte. Para obter suporte completo contínuo, você deve migrar seus aplicativos para o modelo de trabalho isolado.
5 Você não pode executar aplicativos .NET 10 no Linux no plano de consumo. Para executar no Linux, em vez disso, você deve usar o plano de consumo flex.
Para receber as notícias mais recentes sobre as versões de Azure Functions, incluindo a remoção de versões secundárias específicas mais antigas, acompanhe os comunicados de Serviço de Aplicativo do Azure.
Estrutura do projeto
Um projeto do .NET para o Azure Functions que usa o modelo de trabalho isolado é basicamente um projeto de aplicativo de console do .NET direcionado a um runtime do .NET com suporte. Os seguintes arquivos são os arquivos básicos necessários em qualquer projeto isolado do .NET:
- Arquivo de projeto C# (.csproj) que define o projeto e as dependências.
- Arquivo Program. cs que é o ponto de entrada para o aplicativo.
- Todos os arquivos de código que definem suas funções.
- Arquivo host.json que define a configuração compartilhada por funções em seu projeto.
- Arquivo local.settings.json que define as variáveis de ambiente usadas pelo projeto quando executadas localmente em seu computador.
Para obter exemplos completos, confira o projeto de exemplo do .NET 8 e o projeto de exemplo do .NET Framework 4.8.
Referências de pacote
Um projeto .NET para o Azure Functions que usa o modelo de trabalho isolado usa um conjunto exclusivo de pacotes para funcionalidades principais e extensões de associação.
Pacotes principais
Para executar suas funções do .NET em um processo de trabalho isolado, você precisa dos seguintes pacotes:
As versões mínimas desses pacotes dependem da versão do .NET de destino:
| Versão do .NET | Microsoft.Azure.Functions.Worker |
Microsoft.Azure.Functions.Worker.Sdk |
|---|---|---|
| .NET 10 | 2.50.0 ou posterior | 2.0.5 ou posterior |
| .NET 9 | 2.0.0 ou posterior | 2.0.0 ou posterior |
| .NET 8 | 1.16.0 ou posterior | 1.11.0 ou posterior |
| .NET Framework | 1.16.0 ou posterior | 1.11.0 ou posterior |
Versão 2.x
As versões 2.x dos principais pacotes alteram as estruturas com suporte e trazem suporte para novas APIs do .NET a partir dessas versões mais recentes. Ao atualizar para as versões 2.x, anote as seguintes alterações:
- A partir da versão 2.0.0 do Microsoft.Azure.Functions.Worker.Sdk:
- O SDK inclui configurações padrão para builds de contêiner do SDK.
- O SDK inclui suporte para
dotnet runquando o Azure Functions Core Tools é instalado. No Windows, instale as Ferramentas Principais por meio de um mecanismo diferente do NPM.
- A partir da versão 2.0.0 do Microsoft.Azure.Functions.Worker:
- Essa versão adiciona suporte para
IHostApplicationBuilder. Alguns exemplos nesse painel incluem guias para mostrar alternativas usandoIHostApplicationBuilder. Esses exemplos exigem as versões 2.x. - A validação de escopo do provedor de serviços está incluída por padrão se executada em um ambiente de desenvolvimento. Esse comportamento corresponde ao ASP.NET Core.
- A opção
EnableUserCodeExceptionestá habilitada por padrão. A propriedade agora está marcada como obsoleta. - A opção
IncludeEmptyEntriesInMessagePayloadestá habilitada por padrão. Com essa opção ativada, os conteúdos de gatilho que representam coleções sempre incluem entradas vazias. Por exemplo, se uma mensagem for enviada sem um corpo, uma entrada vazia ainda estará presente nos dados do gatilhostring[]. A inclusão de entradas vazias facilita a referência cruzada com matrizes de metadados que a função também pode referenciar. Você pode desabilitar esse comportamento definindoIncludeEmptyEntriesInMessagePayloadparafalsena configuração do serviçoWorkerOptions. - A classe
ILoggerExtensionsé renomeada paraFunctionsLoggerExtensions. A renomeação impede um erro de chamada ambígua ao usarLogMetric()em uma instânciaILogger. - Para aplicativos que usam
HttpResponseData, oWriteAsJsonAsync()método não define mais o código de status como200 OK. No 1.x, esse comportamento substituiu outros códigos de erro que você definiu.
- Essa versão adiciona suporte para
- As versões 2.x removem o suporte ao TFM do .NET 5.
Pacotes de extensão
Como as funções de processo de trabalho isolado do .NET usam tipos de associação diferentes, elas exigem um conjunto exclusivo de pacotes de extensão de associação.
Você encontra esses pacotes de extensão em Microsoft.Azure.Functions.Worker.Extensions.
Inicialização e configuração
Quando você usar o modelo de trabalho isolado, terá acesso à inicialização do seu aplicativo de funções, que geralmente está em Program.cs. Você é responsável por criar e iniciar sua própria instância de host. Assim, você também tem acesso direto ao pipeline de configuração para seu aplicativo. Com o processo de trabalho isolado das funções do .NET você pode adicionar configurações com mais facilidade, injetar dependências e executar seu middleware.
Para usar IHostApplicationBuilder, seu aplicativo deve usar a versão 2.x ou posterior dos principais pacotes.
O código a seguir mostra um exemplo de pipeline 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 chamar Build() no IHostApplicationBuilder, você deve:
- Se você quiser usar a integração com o ASP.NET Core, chame
builder.ConfigureFunctionsWebApplication(). - Se você estiver escrevendo seu aplicativo usando F#, talvez precise registrar algumas extensões de associação. Confira a documentação de configuração da extensão Blobs, da extensão Tabelas e da extensão Cosmos DB quando planejar usar essas extensões em um aplicativo F#.
- Configure todos os serviços ou configuração de aplicativo necessários para seu projeto. Confira Configuração para obter detalhes.
- Se você planeja usar o Application Insights, precisará chamar
AddApplicationInsightsTelemetryWorkerService()eConfigureFunctionsApplicationInsights()em relação à propriedadeServicesdo construtor. Consulte Application Insights para obter detalhes.
Se o projeto for direcionado para o .NET Framework 4.8, você também precisará adicionar FunctionsDebugger.Enable(); antes de criar o HostBuilder. Essa deve ser a primeira linha de seu método Main(). Para mais informações, confira Depuração ao direcionar o .NET Framework.
O IHostApplicationBuilder é usado para criar e retornar uma instância IHost totalmente inicializada, que você executa de forma assíncrona para iniciar seu aplicativo de funções.
await host.RunAsync();
Configuração
O tipo de construtor que você usa determina como configurar o aplicativo.
Use o FunctionsApplication.CreateBuilder() método para adicionar as configurações necessárias para que o aplicativo de funções seja executado. O método inclui a seguinte funcionalidade:
- Conjunto padrão de conversores.
- Defina o JsonSerializerOptions padrão para ignorar maiúsculas e minúsculas nos nomes de propriedade.
- Integrar com o log de Azure Functions.
- Middleware de associação de saída e recursos.
- Middleware de execução de função.
- Suporte a gRPC padrão.
- Aplicar outros padrões de Host.CreateDefaultBuilder().
Você tem acesso ao pipeline do construtor, para que possa definir configurações específicas do aplicativo durante a inicialização. Você pode chamar métodos de extensão na propriedade Configuration do construtor para adicionar quaisquer fontes de configuração exigidas pelo seu código. Para obter mais informações sobre a configuração do aplicativo, consulte Configuração no ASP.NET Core.
Essas configurações se aplicam somente ao código de trabalho que você cria. Eles não influenciam diretamente a configuração do host das Funções ou os gatilhos e vinculações. Para fazer alterações na configuração do host das funções ou na configuração de gatilhos e associações, use o arquivo host.json.
Observação
As fontes de configuração personalizadas não podem ser usadas para a configuração de gatilhos e associações. A configuração de gatilho e associação deve estar disponível para a plataforma do Functions e não apenas para o código do aplicativo. Você pode fornecer essa configuração por meio das configurações do aplicativo, das referências do Key Vault ou dos recursos de referências da Configuração de Aplicativo.
Injeção de dependência
O modelo de trabalho isolado usa mecanismos padrão do .NET para injetar serviços.
Quando você utilizar um IHostApplicationBuilder, use sua propriedade Services para acessar o IServiceCollection. O exemplo a seguir injeta uma dependência de serviço singleton:
builder.Services.AddSingleton<IHttpResponderService, DefaultHttpResponderService>();
Este código requer using Microsoft.Extensions.DependencyInjection;. Para saber mais, confira Injeção de dependência em ASP.NET Core.
Registrar clientes do Azure
Use a injeção de dependência para interagir com outros serviços do Azure. Você pode injetar clientes do SDK do Azure para .NET usando o pacote Microsoft.Extensions.Azure . Depois de instalar o pacote, registre os clientes chamando AddAzureClients() na coleção de serviços no Program.cs. O seguinte exemplo configura um cliente nomeado para os Blobs do Azure:
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();
O exemplo a seguir mostra como você pode usar esse registro e tipos de SDK para copiar o conteúdo do blob como um fluxo de um contêiner para outro usando um cliente injetado:
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!");
}
}
}
O ILogger<T> neste exemplo também é obtido por meio da injeção de dependência, portanto, ele é automaticamente registrado. Para saber mais sobre as opções de configuração do registro em log, confira Registro em log.
Dica
O exemplo usa uma cadeia de caracteres literal para o nome do cliente em ambos Program.cs e na função. Em vez disso, considere usar uma cadeia de caracteres de constante compartilhada definida na classe de função. Por exemplo, você pode adicionar public const string CopyStorageClientName = nameof(_copyContainerClient); e fazer referência a BlobCopier.CopyStorageClientName em ambos os locais. Você também pode definir o nome da seção de configuração com a função, em vez de em Program.cs.
Middleware
O modelo de trabalhador isolado também dá suporte ao registro de middleware, utilizando novamente um modelo semelhante ao existente no ASP.NET. Esse modelo oferece a capacidade de injetar a lógica no pipeline de invocação e as funções before e after são executadas.
O método de extensão ConfigureFunctionsWorkerDefaults tem uma sobrecarga que permite registrar seu próprio middleware, como você vê no exemplo a seguir.
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();
O UseWhen método de extensão registra um middleware que é executado condicionalmente. Você deve passar um predicado que retorna um valor booliano para esse método. O middleware participa do pipeline de processamento de invocação quando o predicado retorna true.
Os métodos de extensão a seguir no FunctionContext facilitam o trabalho com middleware no modelo isolado.
| Método | Descrição |
|---|---|
GetHttpRequestDataAsync |
Obtém a instância de HttpRequestData quando chamada por um gatilho HTTP. Esse método retorna uma instância de ValueTask<HttpRequestData?>, o que é útil quando você deseja ler dados de mensagem, como cookies e cabeçalhos de solicitação. |
GetHttpResponseData |
Obtém a instância de HttpResponseData quando chamada por um gatilho HTTP. |
GetInvocationResult |
Obtém uma instância de InvocationResult, que representa o resultado da execução da função atual. Use a propriedade Value para obter ou definir o valor conforme necessário. |
GetOutputBindings |
Obtém as entradas de associação de saída para a execução da função atual. Cada entrada no resultado desse método é do tipo OutputBindingData. Você pode usar a propriedade Value para obter ou definir o valor conforme necessário. |
BindInputAsync |
Associa um item de associação de entrada para a instância de BindingMetadata solicitada. Por exemplo, use esse método quando você tiver uma função com uma BlobInput associação de entrada que precisa ser usada pelo middleware. |
Este exemplo mostra uma implementação de middleware que lê a HttpRequestData instância e atualiza a instância durante a HttpResponseData execução da função:
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);
}
}
Esse middleware verifica a presença de um cabeçalho de solicitação específico (x-correlationId). Quando o cabeçalho está presente, o middleware usa o valor do cabeçalho para carimbar um cabeçalho de resposta. Caso contrário, ele gera um novo valor GUID e usa esse valor para carimbar o cabeçalho de resposta.
Dica
O padrão mostrado anteriormente da configuração de cabeçalhos de resposta depois await next(context) pode não funcionar de forma confiável em todos os cenários. Esse problema é particularmente verdadeiro ao usar a integração do ASP.NET Core ou em determinadas configurações de runtime em que o fluxo de resposta pode já ter sido enviado. Para garantir que os cabeçalhos estejam definidos corretamente, considere recuperar a resposta context.GetInvocationResult().Value e definir cabeçalhos antes que a resposta seja retornada de sua função, em vez de tentar modificá-los no middleware após a conclusão da execução da função.
Para obter um exemplo mais completo de como usar o middleware personalizado em seu aplicativo de funções, consulte o exemplo de referência de middleware personalizado.
Personalizando a serialização JSON
O modelo de trabalho isolado usa System.Text.Json por padrão. Você pode personalizar o comportamento do serializador configurando serviços como parte do arquivo Program.cs. Esta seção aborda a serialização de uso geral e não influencia a serialização JSON do gatilho HTTP com a integração do ASP.NET Core, que você deve configurar separadamente.
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 serialização, instale o Microsoft.Azure.Core.NewtonsoftJson pacote. Em seguida, no registro do serviço, reatribua a Serializer propriedade na WorkerOptions configuração. O exemplo a seguir mostra essa configuração usando ConfigureFunctionsWebApplication, mas também funciona para ConfigureFunctionsWorkerDefaults:
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 reconhecidos como funções
Um método de função é um método público de uma classe pública com um atributo Function aplicado ao método e um atributo disparo aplicado a um parâmetro de entrada, conforme mostrado no exemplo a seguir:
[Function(nameof(QueueInputOutputFunction))]
[QueueOutput("output-queue")]
public string[] QueueInputOutputFunction([QueueTrigger("input-queue")] Album myQueueItem, FunctionContext context)
O atributo de gatilho especifica o tipo de gatilho e associa dados de entrada a um parâmetro de método. A função de exemplo anterior é disparada por uma mensagem de fila e a mensagem da fila é passada para o método no myQueueItem parâmetro.
O atributo Function marca o método como um ponto de entrada da função. O nome deve ser exclusivo em um projeto, começar com uma letra e conter apenas letras, números _e -até 127 caracteres de comprimento. Modelos de projeto geralmente criam um método chamado Run, mas o nome do método pode ser qualquer nome de método C# válido. O método deve ser um membro público de uma classe pública. Em geral, deve ser um método de instância para que os serviços possam ser transmitidos via injeção de dependência.
Parâmetros de função
Aqui estão alguns dos parâmetros que você pode incluir como parte de uma assinatura de método de função:
- Associações, que são marcadas como tal decorando os parâmetros como atributos. A função deve conter exatamente um parâmetro de gatilho.
- Um objeto de contexto de execução, que fornece informações sobre a invocação atual.
- Um token de cancelamento, usado para desligamento seguro.
Contexto de execução
No modelo de trabalho isolado, o processo de trabalho passa um objeto FunctionContext para seus métodos de função. Esse objeto permite que você obtenha uma instância ILogger para gravar nos logs chamando o método GetLogger e fornecendo uma cadeia de caracteres categoryName. Você pode usar esse contexto para obter um ILogger sem precisar usar a injeção de dependência. Para obter mais informações, veja Registro em log.
Tokens de cancelamento
Uma função pode aceitar um parâmetro cancellationToken , que permite que o sistema operacional notifique seu código quando a função estiver prestes a ser encerrada. Você pode usar essa notificação para certificar-se de que a função não finalize inesperadamente de uma maneira que os dados fiquem em um estado inconsistente.
As funções .NET executadas em um processo de trabalho isolado dão suporte a tokens de cancelamento. O exemplo a seguir gera uma exceção quando uma solicitação de cancelamento é recebida:
[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);
}
}
O exemplo a seguir executa ações de limpeza quando uma solicitação de cancelamento é recebida:
[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);
}
}
Cenários que levam ao cancelamento
O token de cancelamento é sinalizado quando a invocação da função é cancelada. Vários motivos podem levar a um cancelamento, e esses motivos variam dependendo do tipo de gatilho que está sendo usado. Alguns motivos comuns são:
- Desconexão do cliente: o cliente que está invocando sua função se desconecta. Esse motivo é mais provável para funções de gatilho HTTP.
- Reinicialização do aplicativo de funções: você ou a plataforma reiniciam (ou param) o aplicativo de funções na mesma hora em que uma invocação é solicitada. Uma reinicialização pode ocorrer devido a movimentos de instância de trabalho, atualizações de instância de trabalho ou dimensionamento.
Considerações sobre cancelamento
As invocações em voo durante um evento de reinicialização podem ser repetidas dependendo de como foram disparadas. Para obter mais informações, consulte a documentação de nova tentativa.
O host envia a invocação para o trabalhador mesmo que o token de cancelamento seja cancelado antes do host poder enviar a solicitação de invocação para o trabalhador.
Se você não quiser que invocações pré-canceladas sejam enviadas ao trabalhador, adicione a propriedade
SendCanceledInvocationsToWorkerao arquivohost.jsonpara desabilitar esse comportamento.Este exemplo mostra um
host.jsonarquivo que usa esta propriedade:{ "version": "2.0", "SendCanceledInvocationsToWorker": "false" }Definir
SendCanceledInvocationsToWorkercomofalsepode resultar em uma exceçãoFunctionInvocationCanceledcom o seguinte log:O cancelamento foi solicitado. A solicitação de invocação com a ID '{invocationId}' é cancelada e não será enviada ao trabalhador.
Essa exceção ocorre quando o token de cancelamento é cancelado (como resultado de um dos eventos descritos anteriormente) antes que o host envie uma solicitação de invocação de entrada para o trabalhador. Essa exceção pode ser ignorada com segurança e é esperada quando
SendCanceledInvocationsToWorkerforfalse.
Associações
Defina associações usando atributos em métodos, parâmetros e tipos de retorno. As associações podem fornecer dados como cadeias de caracteres, matrizes e tipos serializáveis, como POCOs (objetos de classe antiga simples). Para algumas extensões de associação, você também pode associar a tipos específicos do serviço definidos em SDKs de serviço.
Para os gatilhos HTTP, confira a seção Gatilho HTTP.
Para obter um conjunto completo de exemplos de referência que usam gatilhos e associações com funções de processo de trabalho isoladas, consulte o exemplo de referência de extensões de associação.
Associações de entrada
Uma função pode ter zero ou mais associações de entrada que passam dados para a função. Assim como os gatilhos, você define associações de entrada aplicando um atributo de associação a um parâmetro de entrada. Quando a função é executada, o tempo de execução tenta obter os dados especificados na associação. Os dados solicitados geralmente dependem das informações fornecidas pelo gatilho por meio de parâmetros de associação.
Associações de saída
Para gravar em uma associação de saída, você deve aplicar um atributo de associação de saída ao método de função. Esse atributo define como escrever no serviço vinculado. O valor retornado do método é gravado na associação de saída. Por exemplo, o exemplo a seguir grava um valor de cadeia de caracteres em uma fila de mensagens chamada output-queue usando uma associação de saída:
[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;
}
Várias associações de saída
Os dados gravados em uma associação de saída são sempre o valor de retorno da função. Se você precisar gravar em mais de uma associação de saída, deverá criar um tipo de retorno personalizado. Esse tipo de retorno deve ter o atributo de associação de saída aplicado a uma ou mais propriedades da classe. O exemplo a seguir é uma função acionada por HTTP que usa a integração do ASP.NET Core e grava tanto na resposta HTTP quanto em uma associação de saída de fila.
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; }
}
}
Ao usar tipos de retorno personalizados para várias associações de saída com a integração do ASP.NET Core, você deve adicionar o [HttpResult] atributo à propriedade que fornece o resultado. O atributo HttpResult está disponível ao usar o SDK 1.17.3-preview2 ou posterior, junto a versão 3.2.0 ou posterior da extensão HTTP e a versão 1.3.0 ou posterior da extensão ASP.NET Core.
Tipos de SDK
Para alguns tipos de associação específicos ao serviço, você pode fornecer dados de associação usando tipos de SDKs de serviço e estruturas. Esses tipos oferecem funcionalidades além do que uma cadeia de caracteres serializada ou um objeto CLR (POCO - Plain-Old CLR Object) simples podem fornecer. Para usar os tipos mais recentes, atualize seu projeto para usar versões mais recentes de dependências principais.
| Dependência | Requisito de versão |
|---|---|
| Microsoft.Azure.Functions.Worker | 1.18.0 ou mais recente |
| Microsoft.Azure.Functions.Worker.Sdk | 1.13.0 ou mais recente |
Ao testar tipos de SDK localmente em seu computador, você também precisará usar o Azure Functions Core Tools, versão 4.0.5000 ou posterior. Você pode verificar sua versão atual usando o func --version comando.
Cada extensão de associação também tem seu próprio requisito de versão mínima, que é descrito nos artigos de referência das extensões. Atualmente, essas extensões de associação dão suporte a tipos de SDK:
| Extension | Tipos | Nível de suporte |
|---|---|---|
| Armazenamento de Blobs do Azure | BlobClientBlobContainerClientBlockBlobClientPageBlobClientAppendBlobClient |
Gatilho: GA Entrada: GA |
| Azure Cosmos DB | CosmosClientDatabaseContainer |
Entrada: GA |
| Grade de Eventos do Azure | CloudEventEventGridEvent |
Gatilho: GA |
| Hubs de eventos do Azure | EventDataEventHubProducerClient |
Gatilho: GA |
| Armazenamento de Filas do Azure | QueueClientQueueMessage |
Gatilho: GA |
| Barramento de Serviço do Azure | ServiceBusClientServiceBusReceiverServiceBusSenderServiceBusMessage |
Gatilho: GA |
| Armazenamento de Tabelas do Azure | TableClientTableEntity |
Entrada: GA |
Considerações sobre tipos de SDK:
- Ao usar expressões de associação que dependem de dados de gatilho, não é possível usar os tipos de SDK do próprio gatilho.
- Para cenários de saída em que você pode usar um tipo de SDK, crie e trabalhe com clientes do SDK diretamente em vez de usar uma associação de saída.
- O gatilho do Azure Cosmos DB usa o feed de alterações do Azure Cosmos DB e expõe itens de feed de alterações como tipos serializáveis JSON. Como resultado, não há suporte para tipos de SDK para esse disparador.
Gatilho HTTP
Os gatilhos HTTP permitem que uma função seja invocada por uma solicitação HTTP. Você pode usar duas abordagens diferentes:
- Um modelo de integração ASP.NET Core que usa conceitos familiares aos desenvolvedores ASP.NET Core
- Um modelo interno, que não requer dependências extras e usa tipos personalizados para solicitações e respostas HTTP. Essa abordagem é mantida para compatibilidade com versões anteriores com aplicativos de trabalho isolados do .NET anteriores.
Integração do ASP.NET Core
Esta seção mostra como trabalhar com os objetos de solicitação e resposta HTTP subjacentes usando tipos de ASP.NET Core, incluindo HttpRequest, HttpResponse e IActionResult. Esse modelo não está disponível para aplicativos direcionados ao .NET Framework, que devem usar o modelo interno.
Observação
Esse modelo não expõe todos os recursos do ASP.NET Core. Especificamente, ele não fornece acesso às funcionalidades de pipeline e roteamento do middleware do ASP.NET Core. A integração do ASP.NET Core exige que você use pacotes atualizados.
Para habilitar a integração do ASP.NET Core para HTTP:
Adicione uma referência em seu projeto ao pacote Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore, versão 1.0.0 ou posterior.
Atualize seu projeto para usar estas versões de pacote específicas:
- Microsoft.Azure.Functions.Worker.Sdk, versão 1.11.0. ou posterior
- Microsoft.Azure.Functions.Worker, versão 1.16.0 ou posterior.
No seu arquivo
Program.cs, atualize a configuração do construtor do host para chamarConfigureFunctionsWebApplication(). Esse método substituiráConfigureFunctionsWorkerDefaults()se você usar esse método de outra forma. O exemplo a seguir mostra uma configuração mínima sem outras personalizações:Observação
Seu aplicativo precisa referenciar a versão 2.0.0 ou posterior de Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore para usar a integração do ASP.NET Core com
IHostApplicationBuilder.using Microsoft.Azure.Functions.Worker.Builder; using Microsoft.Extensions.Hosting; var builder = FunctionsApplication.CreateBuilder(args); builder.ConfigureFunctionsWebApplication(); builder.Build().Run();Atualize as funções disparadas por HTTP existentes para usar os tipos de ASP.NET Core. Este exemplo mostra o
HttpRequestpadrão e umIActionResultusado para uma função simples "olá, mundo":[Function("HttpFunction")] public IActionResult Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req) { return new OkObjectResult($"Welcome to Azure Functions, {req.Query["name"]}!"); }
Serialização JSON com integração do ASP.NET Core
ASP.NET Core tem sua própria camada de serialização e não é afetada pela personalização da configuração geral de serialização. Para personalizar o comportamento de serialização usado para seus gatilhos HTTP, você precisa incluir uma chamada .AddMvc() como parte do registro de serviço. O IMvcBuilder retornado pode ser usado para modificar as configurações de serialização JSON do ASP.NET Core.
Você pode continuar a usar HttpRequestData e HttpResponseData, ao usar integração ASP.NET, embora para a maioria dos aplicativos, é melhor usar HttpRequest e IActionResult. O uso HttpRequestData/HttpResponseData não invoca a camada de serialização do ASP.NET Core e, em vez disso, depende da configuração geral de serialização do trabalho para o aplicativo. No entanto, quando a integração do ASP.NET Core estiver habilitada, talvez ainda seja necessário adicionar a configuração. O comportamento padrão do ASP.NET Core é não permitir E/S síncrona. Para usar um serializador personalizado que não dá suporte à E/S assíncrona, como NewtonsoftJsonObjectSerializer, você precisa habilitar a E/S síncrona para seu aplicativo configurando o KestrelServerOptions.
O exemplo a seguir mostra como configurar JSON.NET (Newtonsoft.Json) e o pacote NuGet Microsoft.AspNetCore.Mvc.NewtonsoftJson para serialização usando esta abordagem:
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();
Modelo HTTP interno
No modelo interno, o sistema converte a mensagem de solicitação HTTP de entrada em um objeto HttpRequestData que ele passa para a função. Esse objeto fornece dados da solicitação, incluindo Headers, Cookies, Identities, URL e uma mensagem opcional Body. Esse objeto representa a solicitação HTTP, mas não está diretamente conectado ao ouvinte HTTP subjacente ou à mensagem recebida.
Da mesma forma, a função retorna um objeto HttpResponseData, que fornece dados usados para criar a resposta HTTP, incluindo a mensagem StatusCode, Headers e, opcionalmente, uma mensagem Body.
O exemplo a seguir demonstra o uso HttpRequestData e HttpResponseData:
[Function(nameof(HttpFunction))]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequestData req,
FunctionContext executionContext)
{
var logger = executionContext.GetLogger(nameof(HttpFunction));
logger.LogInformation("message logged");
var response = req.CreateResponse(HttpStatusCode.OK);
response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
response.WriteString("Welcome to .NET isolated worker !!");
return response;
}
Registro em log
Você pode gravar em logs usando uma instância ILogger<T> ou ILogger. Você pode obter o logger por meio da injeção de dependência de um ILogger<T> ou de um 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}");
}
}
Você também pode obter o registrador de um objeto FunctionContext passado para sua função. Chame o método GetLogger<T> ou GetLogger, transmitindo como valor de cadeia de caracteres o nome da categoria em que os logs são gravados. A categoria geralmente é o nome da função específica da qual os logs são gravados. Para obter mais informações sobre categorias, consulte o artigo de monitoramento.
Use os métodos de ILogger<T> e ILogger para gravar vários níveis de registro, como LogWarning ou LogError. Para obter mais informações sobre os níveis de log, consulte o artigo de monitoramento. Você pode personalizar os níveis de log para componentes adicionados ao seu código registrando filtros:
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 da configuração do seu aplicativo em Program.cs, você também pode definir o comportamento de como os erros são exibidos em seus registros. O comportamento padrão depende do tipo de construtor que você está usando.
Quando você utiliza um IHostApplicationBuilder, as exceções lançadas pelo seu código fluem através do sistema sem alterações. Você não precisa de nenhuma outra configuração.
Application Insights
Você pode configurar seu aplicativo de processo isolado para enviar logs diretamente para o Application Insights. Essa configuração substitui o comportamento padrão de retransmissão de logs por meio do host. A menos que você esteja usando o Aspire, configure a integração direta do Application Insights porque ela fornece controle sobre como esses logs são emitidos.
A integração do Application Insights não está habilitada por padrão em todas as experiências de instalação. Alguns modelos criam projetos do Functions com os pacotes necessários e o código de inicialização comentado. Se você quiser usar a integração do Application Insights, descomente essas linhas no Program.cs e no arquivo .csproj do projeto. As instruções no restante desta seção também descrevem como habilitar a integração.
Se o projeto fizer parte de uma orquestração Aspire, ele usará OpenTelemetry para monitoramento. Não habilite a integração direta do Application Insights em projetos do Aspire. Em vez disso, configure o exportador OpenTelemetry do Azure Monitor como parte do projeto padrão do serviço. Se o projeto Functions usar a integração do Application Insights em um contexto Aspire, o aplicativo apresentará erros na inicialização.
Instalar Pacotes
Para gravar logs diretamente no Application Insights do seu código, adicione referências a estes pacotes em seu projeto:
- Microsoft.Azure.Functions.Worker.ApplicationInsights, versão 1.0.0 ou posterior.
- Microsoft.ApplicationInsights.WorkerService.
Execute os seguintes comandos para adicionar essas referências ao seu projeto:
dotnet add package Microsoft.ApplicationInsights.WorkerService
dotnet add package Microsoft.Azure.Functions.Worker.ApplicationInsights
Configurar inicialização
Depois de instalar os pacotes, chame AddApplicationInsightsTelemetryWorkerService() e ConfigureFunctionsApplicationInsights() durante a configuração de serviço em seu Program.cs arquivo, conforme mostrado no exemplo a seguir:
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();
A chamada para ConfigureFunctionsApplicationInsights() adiciona um ITelemetryModule que escuta um ActivitySource definido por funções. Este módulo cria a telemetria de dependência necessária para dar suporte ao rastreamento distribuído. Para obter mais informações sobre AddApplicationInsightsTelemetryWorkerService() e como usá-lo, consulte Application Insights para aplicativos de Worker Service.
Gerenciar níveis de log
Importante
O host do Functions e o trabalhador de processo isolado têm configuração separada para níveis de log. Qualquer configuração do Application Insights no host.json não afeta o log do worker e, da mesma forma, a configuração em seu código do worker não afeta o log do host. Aplique alterações em ambos os locais se seu cenário exigir personalização em ambas as camadas.
O restante do aplicativo continua a trabalhar com ILogger e ILogger<T>. No entanto, por padrão, o SDK do Application Insights adiciona um filtro de registro que instrui o agente a capturar apenas os avisos e registros mais graves. Você pode configurar os níveis de log no processo de trabalho isolado de uma destas maneiras:
| Método de configuração | Benefícios |
|---|---|
| Em seu código | Promove uma separação mais clara entre as configurações do lado do host e do lado do trabalho. |
Usando appsettings.json |
Útil quando você deseja definir diferentes níveis de log para categorias diferentes sem precisar modificar seu código. |
Para desabilitar o comportamento padrão e capturar todos os níveis de log, remova a regra de filtro como parte da configuração de serviço:
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 obter mais informações sobre como configurar o registro em log, consulte Registro em .NET e Application Insights para aplicativos Worker Service.
Otimizações de desempenho
Esta seção descreve as opções que podem ser habilitadas para melhorar o desempenho da inicialização a frio.
Em geral, seu aplicativo deve usar as versões mais recentes de suas dependências principais. No mínimo, atualize seu projeto da seguinte maneira:
- Atualize Microsoft.Azure.Functions.Worker para a versão 1.19.0 ou posterior.
- Atualize Microsoft.Azure.Functions.Worker.Sdk para a versão 1.16.4 ou posterior.
- Adicione uma referência de estrutura a
Microsoft.AspNetCore.App, a menos que seu aplicativo seja direcionado ao .NET Framework.
O snippet a seguir mostra essa configuração no contexto de um arquivo de projeto:
<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>
Espaços reservados
Espaços reservados são uma funcionalidade de plataforma que melhora a inicialização a frio para aplicativos direcionados ao .NET 6 ou posterior. Para usar essa otimização, você deve ativar os placeholders explicitamente seguindo estas etapas:
Atualize a configuração do projeto para usar as versões de dependência mais recentes, conforme detalhado na seção anterior.
Defina a configuração do
WEBSITE_USE_PLACEHOLDER_DOTNETISOLATEDaplicativo como1. Use este comando az functionapp config appsettings set :az functionapp config appsettings set -g <groupName> -n <appName> --settings 'WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED=1'Neste exemplo, substitua
<groupName>pelo nome do grupo de recursos e substitua<appName>pelo nome do aplicativo de funções.Certifique-se de que a propriedade
netFrameworkVersiondo aplicativo de funções corresponde à estrutura de destino do projeto, que deve ser .NET 6 ou posterior. Use este comando az functionapp config set :az functionapp config set -g <groupName> -n <appName> --net-framework-version <framework>Neste exemplo, substitua
<framework>pela cadeia de versão apropriada, comov8.0, de acordo com sua versão de destino do .NET.Verifique se o aplicativo de funções está configurado para usar um processo de 64 bits. Use este comando az functionapp config set :
az functionapp config set -g <groupName> -n <appName> --use-32bit-worker-process false
Importante
Ao definir a opção WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED1, você deve definir todas as outras configurações do aplicativo de funções corretamente. Caso contrário, seu aplicativo de funções poderá falhar ao iniciar.
Executor otimizado
O executor de função é um componente da plataforma que faz com que as invocações sejam executadas. Uma versão otimizada desse componente é habilitada por padrão, começando com a versão 1.16.2 do SDK. Nenhuma configuração adicional é necessária.
ReadyToRun
Você pode compilar seu aplicativo de funções como binários ReadyToRun. ReadyToRun é uma forma de compilação antecipada que pode melhorar o desempenho de inicialização, para ajudar a reduzir o efeito de inicializações a frio durante a execução em um plano de Consumo. O ReadyToRun está disponível no .NET 6 e requer a versão 4.0 ou posterior do runtime do Azure Functions.
ReadyToRun exige que você compile o projeto em relação à arquitetura de runtime do aplicativo de hospedagem. Quando essas arquiteturas não estão alinhadas, seu aplicativo encontra um erro na inicialização. Selecione o identificador de runtime nesta tabela:
| Sistema operacional | O aplicativo é de 32 bits1 | Identificador de runtime |
|---|---|---|
| Windows | True | win-x86 |
| Windows | Falso | win-x64 |
| Linux | True | N/D (sem suporte) |
| Linux | Falso | linux-x64 |
1 Somente aplicativos de 64 bits são elegíveis para algumas outras otimizações de desempenho.
Para verificar se seu aplicativo Windows tem 32 bits ou 64 bits, execute o seguinte comando da CLI, substituindo <group_name> pelo nome do grupo de recursos e <app_name> pelo nome do aplicativo. Uma saída de "true" indica que o aplicativo é de 32 bits e "false" indica 64 bits.
az functionapp config show -g <group_name> -n <app_name> --query "use32BitWorkerProcess"
Você pode alterar o aplicativo para 64 bits com o seguinte comando, usando as mesmas substituições:
az functionapp config set -g <group_name> -n <app_name> --use-32bit-worker-process false`
Para compilar seu projeto como ReadyToRun, atualize o arquivo de projeto adicionando os elementos <PublishReadyToRun> e <RuntimeIdentifier>. O exemplo a seguir mostra uma configuração para publicação em um aplicativo de funções de 64 bits do Windows.
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>
Se você não quiser definir o <RuntimeIdentifier> como parte do arquivo de projeto, você também pode configurar essa opção como parte do próprio gesto de publicação. Por exemplo, com um aplicativo de funções do Windows de 64 bits, o comando da CLI do .NET é:
dotnet publish --runtime win-x64
No Visual Studio, defina a opção Tempo de Execução de Destino no perfil de publicação como o identificador de runtime correto. Quando definido como o valor padrão de Portátil, ReadyToRun não será usado.
Implantar no Azure Functions
Quando você implanta seu projeto de código de função no Azure, ele deve ser executado em um aplicativo de funções ou em um contêiner do Linux. Você deve criar o aplicativo de funções e outros recursos necessários do Azure antes de implantar seu código.
Você também pode implantar seu aplicativo de funções em um contêiner do Linux. Para obter mais informações, consulte Trabalhar com contêineres e Azure Functions.
Criar recursos do Azure
Você pode criar seu aplicativo de funções e outros recursos necessários no Azure usando um destes métodos:
- Visual Studio: o Visual Studio pode criar recursos para você durante o processo de publicação do código.
- Visual Studio Code: o Visual Studio Code pode se conectar à sua assinatura, criar os recursos necessários para seu aplicativo e publicar seu código.
- CLI do Azure: use a CLI do Azure para criar os recursos necessários no Azure.
- Azure PowerShell: use o Azure PowerShell para criar os recursos necessários no Azure.
- Modelos de implantação: use modelos do ARM e arquivos Bicep para automatizar a implantação dos recursos necessários no Azure. Certifique-se de que o modelo inclui as configurações necessárias.
- Portal do Azure: crie os recursos necessários no portal do Azure.
Publicar seu aplicativo
Depois de criar seu aplicativo de funções e outros recursos necessários no Azure, implante o projeto de código no Azure usando um destes métodos:
- Visual Studio: implantação manual simples durante o desenvolvimento.
- Visual Studio Code: implantação manual simples durante o desenvolvimento.
- Azure Functions Core Tools: implantar o arquivo de projeto da linha de comando.
- Implantação contínua: útil para manutenção contínua, frequentemente em um slot de preparo.
- Modelos de implantação: você pode usar modelos do ARM ou arquivos Bicep para automatizar implantações de pacotes.
Para obter mais informações, confira Tecnologias de implantação do Azure Functions.
Conteúdo da implantação
Muitos dos métodos de implantação usam um arquivo zip. Se você criar o arquivo zip por conta própria, ele deverá seguir a estrutura descrita nesta seção. Se isso não ocorrer, seu aplicativo poderá apresentar erros na inicialização.
O conteúdo da implantação deve corresponder à saída de um comando dotnet publish, embora sem a pasta pai delimitada. O arquivo zip deve ser feito a partir dos seguintes arquivos:
.azurefunctions/extensions.jsonfunctions.metadatahost.jsonworker.config.json- Executável do projeto (um aplicativo de console)
- Outros arquivos e diretórios de suporte emparelham esse executável
O processo de build gera esses arquivos e você não deve editá-los diretamente.
Dica
Você pode usar o func pack comando nas Ferramentas Principais para gerar corretamente um arquivo zip para implantação. Suporte para func pack está atualmente em prévia.
Ao preparar um arquivo zip para implantação, compacte apenas o conteúdo do diretório de saída, não o próprio diretório delimitador. Quando o arquivo é extraído no diretório de trabalho atual, os arquivos listados anteriormente precisam estar imediatamente visíveis.
Requisitos de implantação
Para executar funções .NET no modelo de trabalho isolado no Azure, você precisa atender a alguns requisitos. Os requisitos dependem do sistema operacional:
- Defina FUNCTIONS_WORKER_RUNTIME como
dotnet-isolated. - Defina netFrameworkVersion como a versão desejada.
Ao criar seu aplicativo de funções no Azure usando os métodos na seção anterior, essas configurações necessárias serão adicionadas para você. Ao criar esses recursos usando modelos do ARM ou arquivos Bicep para automação, você deverá defini-los no modelo.
Aspire
Aspire é uma pilha opinativa que simplifica o desenvolvimento dos aplicativos distribuídos na nuvem. Você pode inscrever projetos de modelo de trabalho isolado em orquestrações do Aspire 13. Consulte o Azure Functions com o Aspire para obter mais informações.
Depuração
Ao executar localmente usando o Visual Studio ou o Visual Studio Code, você poderá depurar seu projeto de trabalho isolado do .NET normalmente. No entanto, há dois cenários de depuração que não funcionam conforme o esperado.
Depuração remota usando o Visual Studio
Como seu aplicativo de processo de trabalho isolado é executado fora do runtime do Functions, você precisa anexar o depurador remoto a um processo separado. Para saber mais sobre a depuração usando o Visual Studio, confira Depuração Remota.
Depuração ao direcionar o .NET Framework
Se o projeto isolado for direcionado ao .NET Framework 4.8, você precisará realizar etapas manuais para habilitar a depuração. Essas etapas não serão necessárias se outra estrutura de destino estiver sendo usada.
Seu aplicativo deve começar com uma chamada para FunctionsDebugger.Enable(); como a primeira operação. Isso ocorre no método Main() antes de inicializar um HostBuilder. Seu arquivo Program.cs deve ser semelhante a este:
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();
}
}
}
Em seguida, você precisa anexar manualmente ao processo usando um depurador de .NET Framework. O Visual Studio ainda não faz isso automaticamente para aplicativos .NET Framework de processo de trabalho isolado, e a operação "Iniciar Depuração" deve ser evitada.
No diretório do projeto (ou no diretório de saída de build), execute:
func host start --dotnet-isolated-debug
Isso inicia o trabalho e o processo é interrompido com a seguinte mensagem:
Azure Functions .NET Worker (PID: <process id>) initialized in debug mode. Waiting for debugger to attach...
Em que <process id> é a ID do processo de trabalho. Agora, você pode usar Visual Studio para anexar manualmente ao processo. Para obter instruções sobre essa operação, consulte Como anexar a um processo em execução.
Depois que o depurador for anexado, a execução do processo é retomada e você poderá depurar.
Exibir versões do .NET
Antes do lançamento para o público geral, uma versão do .NET pode ser lançada em um estado Versão prévia ou Entrar em funcionamento. Confira a Política de suporte oficial do .NET para obter detalhes sobre esses estados.
Embora seja possível direcionar uma versão específica a partir de um projeto local do Functions, os aplicativos de funções hospedados no Azure podem não ter essa versão disponível. O Azure Functions só pode ser usado com versões de Versão prévia ou Entrar em funcionamento mencionadas nesta seção.
No momento, o Azure Functions não funciona com versões "Versão prévia" ou "Go-live" do .NET. Confira as Versões com suporte para obter uma lista de versões em disponibilidade geral que você pode usar.
Usar a versão prévia de um SDK do .NET
Para usar o Azure Functions com uma versão prévia do .NET, você precisa atualizar o projeto. Para isso, faça o seguinte:
- Instale a versão relevante do SDK do .NET no desenvolvimento.
- Altere a configuração
TargetFrameworkno arquivo.csproj.
Ao implantar seu aplicativo de funções no Azure, você também precisa garantir que a estrutura esteja disponível para o aplicativo. Durante o período de pré-visualização, algumas ferramentas e experiências podem não apresentar a nova versão preliminar como uma opção. Se você não vir a versão prévia incluída no portal do Azure, por exemplo, poderá usar a API REST, os arquivos Bicep ou a CLI do Azure para configurar a versão manualmente.
Para aplicativos hospedados no Windows, use o seguinte comando da CLI do Azure. Substitua <groupName> pelo nome do grupo de recursos e substitua <appName> pelo nome do aplicativo de funções. Substitua <framework> pela cadeia de caracteres de versão apropriada, como v8.0.
az functionapp config set -g <groupName> -n <appName> --net-framework-version <framework>
Considerações ao usar versões prévias do .NET
Considere o seguinte ao usar o Functions com versões prévias do .NET:
Ao criar suas funções no Visual Studio, você deve usar o Visual Studio Insiders, que dá suporte à criação de projetos do Azure Functions com SDKs de versão prévia do .NET.
Certifique-se de que tem as ferramentas e modelos mais recentes do Functions. Para atualizar suas ferramentas:
- Navegue atéAs Opções>, escolha Azure Functions em Projetos e Soluções>Mais Configurações.
- Selecione Verificar se há atualizações e instale atualizações conforme solicitado.
Durante um período de versão prévia, seu ambiente de desenvolvimento pode ter uma versão mais recente da versão prévia do .NET do que o serviço hospedado. Isso pode fazer com que o aplicativo de funções falhe quando implantado. Para resolver isso, especifique a versão do SDK a ser usada no
global.json.- Execute o comando
dotnet --list-sdkse observe a versão da versão prévia que você está usando no momento durante o desenvolvimento local. - Execute o comando
dotnet new globaljson --sdk-version <SDK_VERSION> --force, em que<SDK_VERSION>é a versão que você está usando localmente. Por exemplo,dotnet new globaljson --sdk-version dotnet-sdk-10.0.100-preview.5.25277.114 --forcefaz com que o sistema use o SDK do .NET 10 Versão Prévia 5 ao compilar seu projeto.
- Execute o comando
Observação
Devido ao carregamento just-in-time das estruturas de versão prévia, os aplicativos de funções executados no Windows podem apresentar tempos de inicialização a frio maiores em comparação com as versões anteriores do GA.