Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Uso de servicios delimitados dentro de
Al registrar implementaciones de IHostedService usando cualquiera de los métodos de extensión de AddHostedService, el servicio se registra como singleton. Puede haber escenarios en los que le gustaría depender de un servicio definido por ámbito. Para obtener más información, consulte Inserción de dependencias en .NET: Duración del servicio.
En este tutorial, aprenderá a:
- Resuelva correctamente las dependencias con un ámbito específico dentro de un singleton BackgroundService.
- Delegar el trabajo a un servicio definido.
- Implemente un
override
de BackgroundService.StopAsync(CancellationToken).
Sugerencia
Todo el código fuente de ejemplo de "Workers in .NET" está disponible en el Explorador de Muestras para su descarga. Para obtener más información, consulte Examinación de ejemplos de código: Trabajos en .NET.
Prerrequisitos
- SDK de .NET 8.0 o posterior
- Un entorno de desarrollo integrado (IDE) de .NET
- No dude en usar visual Studio
Creación de un nuevo proyecto
Para crear un proyecto de Worker Service con Visual Studio, seleccione Archivo>Nuevo>Proyecto... . En el cuadro de diálogo Crear un proyecto, busque "Worker Service" y seleccione la plantilla Worker Service. Si prefiere usar la CLI de .NET, abra su terminal favorito en un directorio de trabajo. Ejecute el comando dotnet new
y reemplace el <Project.Name>
por el nombre del proyecto deseado.
dotnet new worker --name <Project.Name>
Para más información sobre el comando del nuevo proyecto de Worker Service de la CLI de .NET, vea dotnet new worker.
Sugerencia
Si usa Visual Studio Code, puede ejecutar comandos de la CLI de .NET desde el terminal integrado. Para obtener más información, vea Visual Studio Code: Terminal integrado.
Servicios con ámbito definido
Para usar servicios con ámbito dentro de un BackgroundService
, cree un ámbito con la IServiceScopeFactory.CreateScope() API. No se crean ámbitos de forma predeterminada para los servicios hospedados. El servicio en segundo plano con un alcance definido contiene la lógica de la tarea en segundo plano.
namespace App.ScopedService;
public interface IScopedProcessingService
{
Task DoWorkAsync(CancellationToken stoppingToken);
}
La interfaz anterior define un único DoWorkAsync
método. Cree una implementación en una nueva clase denominada 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;
}
}
- ILogger se inyecta en el servicio mediante un constructor principal.
- El método
DoWorkAsync
devuelve unTask
y acepta el CancellationToken.- El método registra el identificador de instancia:
_instanceId
se asigna cada vez que se crea una instancia de la clase.
- El método registra el identificador de instancia:
Reescritura de la clase Worker
Reemplace la clase existente Worker
por el siguiente código de C# y cambie el nombre del archivo a 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);
}
}
En el código anterior, mientras stoppingToken
no se cancela, IServiceScopeFactory
se usa para crear un ámbito. Desde el IServiceScope
, se resuelve el IScopedProcessingService
. Se espera el DoWorkAsync
método y stoppingToken
se pasa al método . Por último, la ejecución se retrasa durante 10 segundos y el bucle continúa. Cada vez que se llama al DoWorkAsync
método , se crea una nueva instancia de DefaultScopedProcessingService
y se registra el identificador de instancia.
Reemplace la plantilla Program.cs contenido del archivo por el siguiente código de C#:
using App.ScopedService;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<ScopedBackgroundService>();
builder.Services.AddScoped<IScopedProcessingService, DefaultScopedProcessingService>();
IHost host = builder.Build();
host.Run();
Los servicios se registran en (Program.cs). El servicio hospedado se registra con el método de extensión AddHostedService.
Para obtener más información sobre el registro de servicios, consulte Inserción de dependencias en .NET.
Comprobación de la funcionalidad del servicio
Para ejecutar la aplicación desde Visual Studio, seleccione F5 o seleccione la opción de menú Iniciar depuración>. Si usa la CLI de .NET, ejecute el dotnet run
comando desde el directorio de trabajo:
dotnet run
Para más información sobre el comando run de la CLI de .NET, consulte dotnet run.
Permitir que la aplicación se ejecute un poco para generar varias llamadas a DoWorkAsync
, registrando así nuevos identificadores de instancia. Verá una salida similar a los registros siguientes:
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.
Si ejecuta la aplicación desde Visual Studio, seleccione Depurar>.... Como alternativa, seleccione Ctrl + C en la ventana de la consola para indicar la cancelación.