0Pricing
C# Academy · レッスン

Worker Serviceプロジェクト

スタンドアロンのWorker Serviceを作成し、DIとロギングを設定して、Windows ServiceまたはLinuxデーモンとしてデプロイします。

「Worker Serviceプロジェクト」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全4レッスンが含まれています。

Worker Serviceとは

Worker Serviceは、長時間実行するバックグラウンドアプリケーションを構築するための.NETプロジェクトテンプレートです。WebサーバーもHTTPエンドポイントもありません。キュー処理、スケジュールされたタスク、デーモン型サービスに適した軽量なホストです。

Worker Serviceの作成

CLIテンプレートを使用して、Worker Serviceプロジェクトのひな形を作成します。最小構成のProgram.csと、BackgroundServiceを継承するWorker.csクラスが生成されます。

# 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

Worker ServiceのProgram.cs

生成されたProgram.csはGeneric Hostを使用します。DI、ロギング、構成を設定し、ワーカーを登録します。Webサーバーがない点を除けば、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
}

Workerの構成とDI

Worker Serviceは、appsettings、環境変数、ユーザーシークレットなど、.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 Serviceのロギング

Generic Hostはロギングを自動的に構成します。構造化ロギングには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 Serviceとして実行する

UseWindowsService()を使用すると、WorkerをWindows Serviceとして実行できます。サービスはOSの起動・停止に連動し、ユーザーがログアウトしても動作を続けます。

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

LinuxのSystemdデーモンとして実行する

UseSystemd()を使用すると、Linuxのsystemdと統合できます。サービスは適切な停止シグナルを受け取り、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 Serviceは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]

実践例:メールダイジェストワーカー

データベースから情報を取得し、メールサービス経由で配信する、日次メールダイジェスト送信用の完全なワーカーです。

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 ServiceプロジェクトとASP.NET Core Web APIプロジェクトの主な違いは何ですか?

まとめ:Worker Serviceプロジェクト

重要なポイント:

  • Worker Service = Generic Host + BackgroundService、Webサーバーなし
  • DI、ロギング、構成を完全にサポートしますが、HTTPはありません
  • Windows Serviceとしてデプロイする場合はUseWindowsService()を使用します
  • journaldと統合されたLinuxデーモンにはUseSystemd()を使用します
  • クラウドネイティブなバックグラウンド処理にはDockerコンテナでデプロイします
  • Worker内でScoped依存関係を使用する場合は、必ずIServiceScopeFactoryを使用します

よくある質問

「Worker Serviceプロジェクト」レッスンは無料ですか?

はい。「Worker Serviceプロジェクト」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全4レッスンが含まれています。

「Worker Serviceプロジェクト」で何を学びますか?

スタンドアロンのWorker Serviceを作成し、DIとロギングを設定して、Windows ServiceまたはLinuxデーモンとしてデプロイします。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C# Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「Worker Serviceプロジェクト」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC# Academyレッスンでコードを書いて実行できますか?

はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. IHostedServiceとBackgroundService
  2. Worker Serviceプロジェクト
  3. 定期タスクとタイマー
  4. Quartz.NETのスケジュールジョブ
← C# Academyに戻る