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.
Implementación de la
Cuando necesite un control finito más allá del proporcionado BackgroundService, puede implementar su propio IHostedService. La IHostedService interfaz es la base de todos los servicios de larga duración en .NET. Las implementaciones personalizadas se registran con el método de extensión AddHostedService<THostedService>(IServiceCollection).
En este tutorial, aprenderá a:
- Implemente las interfaces IHostedService y IAsyncDisposable.
- Cree un servicio con temporizador.
- Registre la implementación personalizada con la inyección de dependencias y el registro de eventos.
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, vea Examinar 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.
Creación de un servicio de temporizador
El servicio en segundo plano basado en temporizador utiliza la clase System.Threading.Timer. El temporizador desencadena el DoWork método . El temporizador está deshabilitado en IHostLifetime.StopAsync(CancellationToken) y se desecha cuando el contenedor de servicios se elimina en IAsyncDisposable.DisposeAsync():
Reemplace el contenido de de la Worker plantilla por el siguiente código de C# y cambie el nombre del archivo a TimerService.cs:
namespace App.TimerHostedService;
public sealed class TimerService(ILogger<TimerService> logger) : IHostedService, IAsyncDisposable
{
private readonly Task _completedTask = Task.CompletedTask;
private int _executionCount = 0;
private Timer? _timer;
public Task StartAsync(CancellationToken stoppingToken)
{
logger.LogInformation("{Service} is running.", nameof(TimerHostedService));
_timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(5));
return _completedTask;
}
private void DoWork(object? state)
{
int count = Interlocked.Increment(ref _executionCount);
logger.LogInformation(
"{Service} is working, execution count: {Count:#,0}",
nameof(TimerHostedService),
count);
}
public Task StopAsync(CancellationToken stoppingToken)
{
logger.LogInformation(
"{Service} is stopping.", nameof(TimerHostedService));
_timer?.Change(Timeout.Infinite, 0);
return _completedTask;
}
public async ValueTask DisposeAsync()
{
if (_timer is IAsyncDisposable timer)
{
await timer.DisposeAsync();
}
_timer = null;
}
}
Importante
Worker era una subclase de BackgroundService. Actualmente, TimerService implementa las interfaces IHostedService y IAsyncDisposable.
TimerService es sealed, y encadena la llamada DisposeAsync desde su instancia _timer. Para obtener más información sobre el "patrón de eliminación en cascada", consulte Implementación de un DisposeAsync método.
Cuando se llama a StartAsync, el temporizador se instancia, iniciando así el temporizador.
Sugerencia
Timer no espera a que finalicen las ejecuciones anteriores de DoWork, por lo que es posible que el enfoque mostrado no sea adecuado para todos los escenarios.
Interlocked.Increment se usa para incrementar el contador de ejecución como una operación atómica, lo que garantiza que varios subprocesos no se actualicen _executionCount simultáneamente.
Reemplace el contenido existente Program por el siguiente código de C#:
using App.TimerHostedService;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<TimerService>();
IHost host = builder.Build();
host.Run();
El servicio se registra en (Program.cs) con el método de extensión AddHostedService. Este es el mismo método de extensión que se usa al registrar BackgroundService subclases, ya que ambos implementan la IHostedService interfaz .
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.
Deja que la aplicación se ejecute durante un tiempo para generar varios incrementos en el contador de ejecuciones. Verá una salida similar a la siguiente:
info: App.TimerHostedService.TimerService[0]
TimerHostedService is running.
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: .\timer-service
info: App.TimerHostedService.TimerService[0]
TimerHostedService is working, execution count: 1
info: App.TimerHostedService.TimerService[0]
TimerHostedService is working, execution count: 2
info: App.TimerHostedService.TimerService[0]
TimerHostedService is working, execution count: 3
info: App.TimerHostedService.TimerService[0]
TimerHostedService is working, execution count: 4
info: Microsoft.Hosting.Lifetime[0]
Application is shutting down...
info: App.TimerHostedService.TimerService[0]
TimerHostedService 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.
Consulte también
Hay varios tutoriales relacionados que se deben tener en cuenta: