0Pricing
C# Academy · บทเรียน

โครงการ Worker Service

สร้าง Worker Service แบบสแตนด์อโลน กำหนดค่า DI และการบันทึกข้อมูล และนำไปใช้งานเป็นบริการ Windows หรือดีมอน Linux

โครงการ Worker Service เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน

บริการ Worker คืออะไร

บริการ Worker คือแม่แบบโครงการ .NET สำหรับสร้างแอปพลิเคชันเบื้องหลังที่ทำงานเป็นเวลานาน โดยไม่มีเซิร์ฟเวอร์เว็บและจุดปลายทาง HTTP โฮสต์ชนิดนี้มีน้ำหนักเบาและเหมาะอย่างยิ่งสำหรับตัวประมวลผลคิว งานตามกำหนดเวลา และบริการแบบดีมอน

การสร้างบริการ Worker

ใช้แม่แบบโครงการจาก CLI เพื่อสร้างโครงร่างโครงการบริการ Worker ระบบจะสร้าง Program.cs แบบพื้นฐานและคลาส Worker.cs ที่สืบทอดจาก 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 ของบริการ Worker

Program.cs ที่สร้างขึ้นใช้โฮสต์ทั่วไป คุณสามารถกำหนดค่า DI การบันทึกข้อมูล การกำหนดค่า และลงทะเบียนบริการ Worker ได้เช่นเดียวกับ ASP.NET Core แต่ไม่มีเซิร์ฟเวอร์เว็บ

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();

คลาส Worker

สืบทอดจาก BackgroundService และใช้งาน ExecuteAsync โฮสต์จะเรียกใช้เมธอดนี้เมื่อเริ่มต้น และส่งโทเคนการยกเลิกที่จะทำงานเมื่อปิดระบบ

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
}

การกำหนดค่าและ DI ในบริการ Worker

บริการ Worker รองรับระบบการกำหนดค่า .NET อย่างครบถ้วน ทั้งการตั้งค่าแอป ตัวแปรสภาพแวดล้อม และข้อมูลลับของผู้ใช้ คุณสามารถฉีด IConfiguration หรือตัวเลือกที่มีชนิดข้อมูลชัดเจนได้

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);
        }
    }
}

การบันทึกข้อมูลในบริการ Worker

โฮสต์ทั่วไปจะกำหนดค่าการบันทึกข้อมูลโดยอัตโนมัติ ใช้ ILogger<T> สำหรับการบันทึกข้อมูลแบบมีโครงสร้าง ในระบบจริง ให้กำหนดค่า Serilog, Application Insights หรือผู้ให้บริการรายอื่น

// 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);

การทำงานเป็นบริการ Windows

ใช้ UseWindowsService() เพื่อให้บริการ Worker ทำงานเป็นบริการ Windows บริการจะเริ่มและหยุดพร้อมระบบปฏิบัติการ และยังคงทำงานต่อได้เมื่อผู้ใช้ออกจากระบบ

// 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

การทำงานเป็นดีมอน Systemd บน Linux

ใช้ UseSystemd() เพื่อผสานการทำงานกับ systemd บน Linux บริการจะได้รับสัญญาณหยุดที่เหมาะสมและผสานเข้ากับการบันทึกข้อมูลของ 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

การทำงานใน Docker

บริการ Worker เหมาะอย่างยิ่งสำหรับคอนเทนเนอร์ Docker ไม่จำเป็นต้องแมปพอร์ต เพียงเรียกใช้กระบวนการวนลูปจนกว่าคอนเทนเนอร์จะหยุดทำงาน

# 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]

ตัวอย่างการใช้งานจริง: บริการ Worker สำหรับสรุปอีเมล

บริการ Worker แบบครบถ้วนที่ส่งสรุปอีเมลรายวัน โดยอ่านข้อมูลจากฐานข้อมูลและส่งต่อผ่านบริการอีเมล

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"); }
        }
    }
}

ตรวจสอบความเข้าใจ

ความแตกต่างหลักระหว่างโครงการบริการ Worker กับโครงการ ASP.NET Core Web API คืออะไร

สรุป: โครงการบริการ Worker

ประเด็นสำคัญ:

  • บริการ Worker = โฮสต์ทั่วไป + BackgroundService โดยไม่มีเซิร์ฟเวอร์เว็บ
  • รองรับ DI การบันทึกข้อมูล และการกำหนดค่าอย่างครบถ้วน เพียงแต่ไม่มี HTTP
  • UseWindowsService() สำหรับการนำบริการไปใช้งานบน Windows
  • UseSystemd() สำหรับดีมอนบน Linux ที่ผสานกับ journald
  • นำไปใช้งานในคอนเทนเนอร์ Docker สำหรับการประมวลผลเบื้องหลังแบบคลาวด์เนทีฟ
  • ใช้ IServiceScopeFactory สำหรับการพึ่งพาที่มีขอบเขตในบริการ Worker เสมอ

คำถามที่พบบ่อย

บทเรียน “โครงการ Worker Service” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “โครงการ Worker Service” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “โครงการ Worker Service”

สร้าง Worker Service แบบสแตนด์อโลน กำหนดค่า DI และการบันทึกข้อมูล และนำไปใช้งานเป็นบริการ Windows หรือดีมอน Linux คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “โครงการ Worker Service” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม

ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. IHostedService และ BackgroundService
  2. โครงการ Worker Service
  3. งานตามช่วงเวลาและตัวจับเวลา
  4. งานตามกำหนดเวลาด้วย Quartz.NET
← กลับไปที่ C# Academy