.NET の Worker サービス
実行時間の長いサービスを作成するには、次のようなさまざまな理由があります。
- CPU 負荷の高いデータの処理。
- バックグラウンドでの作業項目のキューイング。
- スケジュールに基づく時間ベースの操作の実行。
バックグラウンド サービスの処理には、通常、ユーザー インターフェイス (UI) は含まれませんが、それを中心にして UI を作成することはできます。 .NET Framework の初期には、Windows 開発者がこのような理由で Windows サービスを作成することがありました。 現在の .NET では、BackgroundService を使用できます。これは、IHostedService の実装であるか、または独自に実装します。
.NET は Windows に限定されなくなりました。 クロスプラットフォームのバックグラウンド サービスを開発できます。 ホステッド サービスは、ログ記録、構成、依存関係の挿入 (DI) に対応しています。 これらはライブラリの拡張機能スイートの一部であり、汎用ホストで動作するすべての .NET ワークロードの基礎であることを意味します。
用語
多くの用語が誤って同義として使用されます。 このセクションでは、そのような用語のいくつかを定義し、意図を明確にします。
- バックグラウンド サービス: 型のことです。
- ホステッド サービス: の実装であるか、または IHostedService 自体を示します。
- 実行時間の長いサービス: 継続的に実行されるサービス。
- Windows サービス: Windows サービス インフラストラクチャは、当初は .NET Framework 中心でしたが、現在は .NET 経由でアクセスできます。
- Worker サービス: Worker サービス テンプレートのことです。
ワーカー サービス テンプレート
Worker サービス テンプレートは、.NET CLI および Visual Studio で使用できます。 詳細については、.NET CLI の のテンプレートに関する記事を参照してください。 このテンプレートは、Program
クラスと Worker
クラスで構成されています。
using App.WorkerService;
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddHostedService<Worker>();
})
.Build();
await host.RunAsync();
前の Program
クラスは次のとおりです。
- 既定の IHostBuilder を作成します。
- ConfigureServices を呼び出して、AddHostedService でのホステッド サービスとして
Worker
を追加します。 - ビルダーから IHost をビルドします。
host
インスタンスでRun
を呼び出します。アプリが実行されます。
ヒント
既定では、ワーカー サービス テンプレートによってサーバーのガベージ コレクション (GC) は有効にはなりません。 実行時間の長いサービスを必要とするすべてのシナリオで、この既定の状態のパフォーマンスへの影響を考慮する必要があります。 サーバーの GC を有効にするには、プロジェクト ファイルに ServerGarbageCollection
ノードを追加します。
<PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection>
</PropertyGroup>
パフォーマンスに関する考慮事項の詳細については、「サーバーの GC」を参照してください。 サーバーの GC を構成する方法の詳細については、サーバーの GC の構成例を参照してください。
テンプレートの Program.cs ファイルは、最上位レベルのステートメントを使用して書き換えることができます。
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using App.WorkerService;
using IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
})
.Build();
await host.RunAsync();
これは、元のテンプレートと機能的に同等です。 C# 9.0 の機能の詳細については、「C# 9.0 の新機能」を参照してください。
Worker
の場合と同様に、テンプレートでは単純な実装が提供されます。
namespace App.WorkerService
{
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
}
}
}
}
上の Worker
クラスは、IHostedService を実装する BackgroundService のサブクラスです。 BackgroundService は abstract class
であり、サブクラスで BackgroundService.ExecuteAsync(CancellationToken) を実装する必要があります。 テンプレートの実装では、ExecuteAsync
が 1 秒に 1 回ループして、プロセスがキャンセルを通知されるまで、現在の日付と時刻をログに記録します。
プロジェクト ファイル
Worker サービス テンプレートは、次のプロジェクト ファイル Sdk
に依存しています。
<Project Sdk="Microsoft.NET.Sdk.Worker">
詳細については、「.NET プロジェクト SDK」を参照してください。
NuGet パッケージ
ワーカー サービス テンプレートに基づくアプリは Microsoft.NET.Sdk.Worker
SDK を使用し、Microsoft.NET.Sdk.Worker
パッケージへの明示的なパッケージ参照を含んでいます。
コンテナーとクラウドの適応可能性
最新の .NET ワークロードでは、コンテナーが実用的な選択肢です。 Visual Studio で Worker サービス テンプレートから長時間実行されるサービスを作成する場合は、Docker サポートにオプトインできます。 これにより、.NET アプリをコンテナー化する Dockerfile が作成されます。 Dockerfile は、イメージをビルドするための一連の手順です。 .NET アプリの場合、Dockerfile は通常、ソリューション ファイルの隣にあるディレクトリのルートに存在します。
# See https://aka.ms/containerfastmode to understand how Visual Studio uses this
# Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/runtime:5.0 AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["background-service/App.WorkerService.csproj", "background-service/"]
RUN dotnet restore "background-service/App.WorkerService.csproj"
COPY . .
WORKDIR "/src/background-service"
RUN dotnet build "App.WorkerService.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "App.WorkerService.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "App.WorkerService.dll"]
前の Dockerfile のステップには、次のものが含まれます。
mcr.microsoft.com/dotnet/runtime:6.0
の基本イメージのエイリアスbase
としての設定。- /app への作業ディレクトリの変更。
mcr.microsoft.com/dotnet/sdk:6.0
イメージからのbuild
エイリアスの設定。- /src への作業ディレクトリの変更。
- コンテンツのコピーと .NET アプリの発行。
- このアプリは、
dotnet publish
コマンドを使用して発行されます。
- このアプリは、
mcr.microsoft.com/dotnet/runtime:6.0
の .NET SDK イメージの再階層化 (base
エイリアス)。- 発行されたビルド出力の /publish からのコピー。
dotnet App.BackgroundService.dll
に委任されるエントリ ポイントの定義。
ヒント
mcr.microsoft.com
の MCR は "Microsoft Container Registry" を表し、公式の Docker Hub の Microsoft のシンジケート化されたコンテナー カタログです。 詳細については、Microsoft によるコンテナー カタログのシンジケート化に関する記事を参照してください。
.NET Worker サービスのデプロイ戦略として Docker をターゲットにする場合、プロジェクト ファイルで考慮することがいくつかあります。
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
<RootNamespace>App.WorkerService</RootNamespace>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.11.1" />
</ItemGroup>
</Project>
前のプロジェクト ファイルの <DockerDefaultTargetOS>
要素では、ターゲットとして Linux
が指定されています。 Windows コンテナーをターゲットにするには、代わりに Windows
を使用します。 テンプレートから Docker サポートが選択されると、パッケージ参照として NuGet パッケージが自動的に追加されます。
.NET での Docker の詳細については、.NET アプリのコンテナー化のチュートリアルに関する記事を参照してください。 Azure へのデプロイの詳細については、Azure への Worker サービスのデプロイのチュートリアルに関する記事を参照してください。
重要
ワーカー サービス テンプレートを使用して "ユーザー シークレット" を活用する場合は、 NuGet パッケージを明示的に参照する必要があります。
ホステッド サービスの拡張性
IHostedService インターフェイスでは、2 つのメソッドが定義されています。
これら 2 つのメソッドは、"ライフサイクル" メソッドとして機能します。これらは、それぞれ、ホストの開始イベントと停止イベントの間に呼び出されます。
注意
StartAsync または StopAsync メソッドがオーバーライドされた場合、サービスが正常にシャットダウンされるように、base
基本クラス メソッドを呼び出す (および await
する) 必要があります。
重要
このインターフェイスは、AddHostedService<THostedService>(IServiceCollection) 拡張メソッドでのジェネリック型パラメーターの制約として機能します。つまり、実装のみが許可されます。 サブクラスで提供されている BackgroundService を使用することも、独自のものを完全に実装することも自由にできます。
関連項目
- BackgroundService サブクラスのチュートリアル:
- .NET で Queue サービスを作成する
- .NET の 内でスコープ付きサービスを使用する
- .NET で を使用して Windows サービスを作成する
- カスタムの IHostedService の実装:
- .NET で インターフェイスを実装する