Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Usar serviços delimitados num
Quando se registam implementações de IHostedService usando qualquer um dos métodos de extensão AddHostedService, o serviço é registado como um singleton. Podem existir cenários em que desejas contar com um serviço delimitado. Para obter mais informações, consulte Injeção de dependência no .NET: Tempos de vida do serviço.
Neste tutorial, aprenderás como:
- Resolva corretamente as dependências com escopo num singleton BackgroundService.
- Delegue o trabalho a um serviço definido.
- Implementar um
overridede BackgroundService.StopAsync(CancellationToken).
Sugestão
Todo o código-fonte de exemplo "Workers in .NET" está disponível no Samples Browser para download. Para obter mais informações, veja Explorar exemplos de código: Trabalhadores em .NET.
Pré-requisitos
- O SDK do .NET 8.0 ou posterior
- Um ambiente de desenvolvimento integrado (IDE) .NET
- Sinta-se à vontade para usar Visual Studio
Criar um novo projeto
Para criar um novo projeto do Serviço de Trabalho com o Visual Studio, selecione Arquivo>Novo Projeto>.... Na caixa de diálogo Criar um novo projeto procure por "Serviço de Trabalhador" e selecione Modelo de Serviço de Trabalhador. 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 comando .NET CLI new worker service project, consulte dotnet new worker.
Sugestão
Se você estiver usando o Visual Studio Code, poderá executar comandos da CLI do .NET a partir do terminal integrado. Para obter mais informações, consulte Visual Studio Code: Integrated Terminal.
Criar serviços com escopo
Para usar serviços com escopo dentro de um BackgroundService, crie um escopo na IServiceScopeFactory.CreateScope() API. Nenhum escopo é criado para um serviço hospedado por padrão. 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
DoWorkAsyncmétodo retorna aTaske 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 DoWorkAsync método é aguardado, e o stoppingToken é passado para o método. Finalmente, a execução é atrasada por 10 segundos e o loop continua. Cada vez que o DoWorkAsync método é chamado, uma nova instância do DefaultScopedProcessingService é criada e o identificador de instância é registrado.
Substitua o conteúdo do arquivo de modelo 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 estão registados em (Program.cs). O serviço hospedado é registrado com o AddHostedService método de extensão.
Para saber mais sobre o registo de serviços, consulte injeção de dependência no .NET.
Verificar a funcionalidade do serviço
Para executar o aplicativo do Visual Studio, selecione F5 ou selecione a opção de menu Depurar>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 .NET CLI run, consulte dotnet run.
Deixe o aplicativo ser executado por um pouco para gerar várias chamadas para DoWorkAsync, registrando assim novos identificadores de instância. Você verá uma saída 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 de dentro do Visual Studio, selecione Depurar>Parar Depuração.... Como alternativa, selecione Ctrl + C na janela do console para sinalizar o cancelamento.