0Pricing
C# Academy · Lección

Proyectos Worker Service

Cree un Worker Service independiente, configure DI y el registro, y despliegue el servicio como un servicio de Windows o un demonio de Linux.

Proyectos Worker Service es una lección gratuita de C# Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de C# Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de C# Academy incluye 4 lecciones en total.

¿Qué es un Worker Service?

Un Worker Service es una plantilla de proyecto de .NET para crear aplicaciones en segundo plano de larga duración: sin servidor web ni endpoints HTTP. Es un host ligero, perfecto para procesadores de colas, tareas programadas y servicios de tipo demonio.

Creación de un Worker Service

Utilice la plantilla de la CLI para crear la estructura de un proyecto Worker Service. Esta genera un Program.cs mínimo y una clase Worker.cs que hereda de BackgroundService.

# Create a new Worker Service project
dotnet new worker -n OrderProcessor

# Generated structure:
# OrderProcessor/
#   Program.cs       — host configuration
#   Worker.cs        — your BackgroundService subclass
#   appsettings.json

Program.cs de Worker Service

El Program.cs generado utiliza el Generic Host. Puede configurar la inyección de dependencias, el registro, la configuración y registrar su worker, igual que en ASP.NET Core, pero sin el servidor web.

using Microsoft.Extensions.Hosting;

var builder = Host.CreateApplicationBuilder(args);

// Register services
builder.Services.AddDbContext<AppDbContext>(opt =>
    opt.UseSqlServer(builder.Configuration.GetConnectionString("Default")));

builder.Services.AddScoped<IOrderRepository, OrderRepository>();
builder.Services.AddHostedService<OrderProcessorWorker>();

var host = builder.Build();
host.Run();

La clase Worker

Herede de BackgroundService e implemente ExecuteAsync. El host lo llama al iniciarse y proporciona un token de cancelación que se activa durante el apagado.

public class OrderProcessorWorker : BackgroundService
{
    private readonly IServiceScopeFactory _factory;
    private readonly ILogger<OrderProcessorWorker> _logger;

    public OrderProcessorWorker(
        IServiceScopeFactory factory,
        ILogger<OrderProcessorWorker> logger)
    {
        _factory = factory;
        _logger  = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken ct)
    {
        while (!ct.IsCancellationRequested)
        {
            using var scope = _factory.CreateScope();
            var repo = scope.ServiceProvider.GetRequiredService<IOrderRepository>();
            var pending = await repo.GetPendingAsync(ct);
            foreach (var order in pending)
                await ProcessOrderAsync(order, ct);
            await Task.Delay(TimeSpan.FromSeconds(10), ct);
        }
    }

    private Task ProcessOrderAsync(Order o, CancellationToken ct) =>
        Task.Delay(100, ct); // placeholder
}

Configuración e inyección de dependencias en Workers

Los Worker Services admiten todo el sistema de configuración de .NET: appsettings, variables de entorno y secretos de usuario. Inyecte IConfiguration u opciones fuertemente tipadas.

builder.Services.Configure<WorkerSettings>(
    builder.Configuration.GetSection("Worker"));

public class OrderProcessorWorker : BackgroundService
{
    private readonly WorkerSettings _settings;

    public OrderProcessorWorker(IOptions<WorkerSettings> opts, ...)
        => _settings = opts.Value;

    protected override async Task ExecuteAsync(CancellationToken ct)
    {
        while (!ct.IsCancellationRequested)
        {
            // ...
            await Task.Delay(_settings.PollIntervalSeconds * 1000, ct);
        }
    }
}

Registro en Worker Services

El Generic Host configura el registro automáticamente. Utilice ILogger<T> para un registro estructurado. En producción, configure Serilog, Application Insights u otro proveedor.

// Add Serilog to a Worker Service
builder.Host.UseSerilog((ctx, logConfig) =>
    logConfig
        .ReadFrom.Configuration(ctx.Configuration)
        .WriteTo.Console()
        .WriteTo.Seq(ctx.Configuration["Seq:ServerUrl"]!));

// Structured logging in the worker:
_logger.LogInformation("Processing {Count} orders at {Time}",
    orders.Count, DateTimeOffset.UtcNow);
_logger.LogError(ex, "Failed to process order {OrderId}", order.Id);

Ejecución como servicio de Windows

Utilice UseWindowsService() para ejecutar su Worker como un servicio de Windows. El servicio se inicia y se detiene con el sistema operativo y sigue ejecutándose aunque los usuarios cierren sesión.

// dotnet add package Microsoft.Extensions.Hosting.WindowsServices

builder.Services.AddWindowsService(options =>
    options.ServiceName = "OrderProcessor");

// Build and publish:
// dotnet publish -c Release -o ./publish

// Install as Windows Service:
// sc create OrderProcessor binpath="C:\services\publish\OrderProcessor.exe"
// sc start OrderProcessor

Ejecución como demonio de Linux con Systemd

Utilice UseSystemd() para integrarse con systemd en Linux. El servicio recibe las señales de detención adecuadas y se integra con el registro de journald.

// dotnet add package Microsoft.Extensions.Hosting.Systemd

builder.Services.AddSystemd();

// Systemd unit file: /etc/systemd/system/orderprocessor.service
// [Unit]
// Description=Order Processor Worker
// [Service]
// Type=notify
// ExecStart=/usr/bin/dotnet /app/OrderProcessor.dll
// Restart=always
// [Install]
// WantedBy=multi-user.target

// Commands:
// sudo systemctl enable orderprocessor
// sudo systemctl start orderprocessor
// sudo journalctl -u orderprocessor -f

Ejecución en Docker

Los Worker Services son ideales para contenedores Docker: no necesitan asignación de puertos; basta con ejecutar el proceso en un bucle hasta que se detenga el contenedor.

# Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
COPY . .
RUN dotnet publish -c Release -o /app

FROM mcr.microsoft.com/dotnet/runtime:9.0
WORKDIR /app
COPY --from=build /app .
ENTRYPOINT ["dotnet", "OrderProcessor.dll"]

# docker-compose.yml:
# services:
#   worker:
#     build: .
#     environment:
#       - ConnectionStrings__Default=Server=db;...
#     depends_on: [db]

Caso real: worker de resúmenes de correo electrónico

Un worker completo que envía resúmenes diarios de correo electrónico leyendo datos de una base de datos y distribuyéndolos mediante un servicio de correo electrónico.

public class EmailDigestWorker : BackgroundService
{
    private readonly IServiceScopeFactory _factory;
    private readonly ILogger<EmailDigestWorker> _log;

    protected override async Task ExecuteAsync(CancellationToken ct)
    {
        // Run daily at midnight UTC
        while (!ct.IsCancellationRequested)
        {
            var now = DateTime.UtcNow;
            var next = now.Date.AddDays(1); // next midnight
            await Task.Delay(next - now, ct);

            using var scope = _factory.CreateScope();
            var mailer = scope.ServiceProvider.GetRequiredService<IDigestMailer>();

            try   { await mailer.SendDailyDigestsAsync(ct); }
            catch (Exception ex) { _log.LogError(ex, "Digest failed"); }
        }
    }
}

Comprobación rápida

¿Cuál es la principal diferencia entre un proyecto Worker Service y un proyecto ASP.NET Core Web API?

Resumen: proyectos Worker Service

Aspectos clave:

  • Worker Service = Generic Host + BackgroundService, sin servidor web
  • Compatibilidad completa con inyección de dependencias, registro y configuración; solo falta HTTP
  • UseWindowsService() para la implementación como servicio de Windows
  • UseSystemd() para un demonio de Linux con integración con journald
  • Impleméntelos en contenedores Docker para el procesamiento en segundo plano nativo de la nube
  • Utilice siempre IServiceScopeFactory para las dependencias con ámbito en el worker

Preguntas frecuentes

¿La lección «Proyectos Worker Service» es gratis?

Sí — el texto completo de «Proyectos Worker Service» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de C# Academy, actualiza a CoddyKit PRO. El curso de C# Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Proyectos Worker Service»?

Cree un Worker Service independiente, configure DI y el registro, y despliegue el servicio como un servicio de Windows o un demonio de Linux. Practicas C# Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar C# Academy?

No se requiere experiencia previa. C# Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.

¿Cuánto tiempo toma la lección «Proyectos Worker Service»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de C# Academy?

Sí. Cada lección de C# Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. IHostedService y BackgroundService
  2. Proyectos Worker Service
  3. Tareas periódicas y temporizadores
  4. Trabajos programados con Quartz.NET
← Volver a C# Academy