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.
Utilize serviços delimitados dentro de um
Quando você registra implementações de IHostedService usando qualquer um dos métodos de extensão de AddHostedService, o serviço é registrado como um singleton. Pode haver cenários em que você gostaria de contar com um serviço com escopo. Para obter mais informações, consulte Injeção de dependência no .NET: tempo de vida do serviço.
Neste tutorial, você aprenderá como:
- Resolva corretamente as dependências com escopo em um singleton BackgroundService.
- Delegar trabalho a um serviço com escopo.
- Implementar um
override
de BackgroundService.StopAsync(CancellationToken).
Dica
Todo o código-fonte de exemplo de "Workers in .NET" está disponível no Navegador de Exemplos para download. Para obter mais informações, confira Procurar exemplos de código: Trabalhos no .NET.
Pré-requisitos
- O SDK .NET 8.0 ou posterior
- Um IDE (ambiente de desenvolvimento integrado) do .NET
- Fique à vontade para usar o Visual Studio
Criar um novo projeto
Para criar um projeto do Serviço de Trabalho com o Visual Studio, selecione Arquivo>Novo>Projeto.... Na caixa de diálogo Criar um projeto, pesquise "Serviço de Trabalho" e selecione o modelo de Serviço de Trabalho. Se você preferir usar a CLI do .NET, abra seu terminal favorito em um diretório de trabalho. Execute o comando dotnet new
e substitua o <Project.Name>
pelo nome do projeto desejado.
dotnet new worker --name <Project.Name>
Para obter mais informações sobre o novo comando do projeto de serviço de trabalho da CLI do .NET, confira dotnet new worker.
Dica
Se você estiver usando o Visual Studio Code, poderá executar comandos da CLI do .NET no terminal integrado. Para obter mais informações, consulte Visual Studio Code: Terminal Integrado.
Criar serviços com escopo definido
Para usar serviços com escopo dentro de um BackgroundService
, crie um escopo com a IServiceScopeFactory.CreateScope() API. Por padrão, nenhum escopo é criado para um serviço hospedado. O serviço em segundo plano com escopo contém a lógica da tarefa em segundo plano.
namespace App.ScopedService;
public interface IScopedProcessingService
{
Task DoWorkAsync(CancellationToken stoppingToken);
}
A interface anterior define um único DoWorkAsync
método. Crie uma implementação em uma nova classe chamada DefaultScopedProcessingService.cs:
namespace App.ScopedService;
public sealed class DefaultScopedProcessingService(
ILogger<DefaultScopedProcessingService> logger) : IScopedProcessingService
{
private readonly string _instanceId = Guid.NewGuid().ToString();
public Task DoWorkAsync(CancellationToken stoppingToken)
{
logger.LogInformation(
"{ServiceName} doing work, instance ID: {Id}",
nameof(DefaultScopedProcessingService),
_instanceId);
return Task.CompletedTask;
}
}
- Um ILogger é injetado no serviço usando um construtor primário.
- O
DoWorkAsync
método retorna umTask
e aceita o CancellationToken.- O método registra o identificador de instância - o
_instanceId
é atribuído sempre que a classe é instanciada.
- O método registra o identificador de instância - o
Reescrever a classe Worker
Substitua a classe existente Worker
pelo seguinte código C# e renomeie o arquivo para ScopedBackgroundService.cs:
namespace App.ScopedService;
public sealed class ScopedBackgroundService(
IServiceScopeFactory serviceScopeFactory,
ILogger<ScopedBackgroundService> logger) : BackgroundService
{
private const string ClassName = nameof(ScopedBackgroundService);
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
logger.LogInformation(
"{Name} is running.", ClassName);
while (!stoppingToken.IsCancellationRequested)
{
using IServiceScope scope = serviceScopeFactory.CreateScope();
IScopedProcessingService scopedProcessingService =
scope.ServiceProvider.GetRequiredService<IScopedProcessingService>();
await scopedProcessingService.DoWorkAsync(stoppingToken);
await Task.Delay(10_000, stoppingToken);
}
}
public override async Task StopAsync(CancellationToken stoppingToken)
{
logger.LogInformation(
"{Name} is stopping.", ClassName);
await base.StopAsync(stoppingToken);
}
}
No código anterior, enquanto o stoppingToken
não é cancelado, o IServiceScopeFactory
é usado para criar um escopo. A partir do IServiceScope
, o IScopedProcessingService
é resolvido. O método DoWorkAsync
é aguardado, e o stoppingToken
é passado para o método. Por fim, a execução é atrasada por 10 segundos e o loop continua. Sempre que o método DoWorkAsync
é chamado, uma nova instância de DefaultScopedProcessingService
é criada e o identificador de instância é registrado.
Substitua o conteúdo do arquivo Program.cs pelo seguinte código C#:
using App.ScopedService;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<ScopedBackgroundService>();
builder.Services.AddScoped<IScopedProcessingService, DefaultScopedProcessingService>();
IHost host = builder.Build();
host.Run();
Os serviços são registrados em (Program.cs). O serviço é registrado como hospedado com o método de extensão AddHostedService.
Para obter mais informações para registrar serviços, confira Injeção de dependência no .NET.
Verificar a funcionalidade do serviço
Para executar o aplicativo no Visual Studio, selecione F5 ou selecione a opção de menu Depuração>Iniciar Depuração. Se você estiver usando a CLI do .NET, execute o dotnet run
comando no diretório de trabalho:
dotnet run
Para obter mais informações sobre o comando dotnet run da CLI do .NET, consulte.
Deixe o aplicativo executar por um tempo para gerar várias chamadas ao DoWorkAsync
, registrando assim novos identificadores de instância. Você verá um resultado semelhante aos seguintes logs:
info: App.ScopedService.ScopedBackgroundService[0]
ScopedBackgroundService is running.
info: App.ScopedService.DefaultScopedProcessingService[0]
DefaultScopedProcessingService doing work, instance ID: 8986a86f-b444-4139-b9ea-587daae4a6dd
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: .\scoped-service
info: App.ScopedService.DefaultScopedProcessingService[0]
DefaultScopedProcessingService doing work, instance ID: 07a4a760-8e5a-4c0a-9e73-fcb2f93157d3
info: App.ScopedService.DefaultScopedProcessingService[0]
DefaultScopedProcessingService doing work, instance ID: c847f432-acca-47ee-8720-1030859ce354
info: Microsoft.Hosting.Lifetime[0]
Application is shutting down...
info: App.ScopedService.ScopedBackgroundService[0]
ScopedBackgroundService is stopping.
Se estiver executando o aplicativo no Visual Studio, selecione Depurar>Parar Depuração.... Como alternativa, selecione Ctrl + C na janela do console para sinalizar o cancelamento.