次の方法で共有


BackgroundService 内でスコープ付きサービスを利用する

IHostedService拡張メソッドのいずれかを使用してAddHostedServiceの実装を登録すると、サービスはシングルトンとして登録されます。 スコープ付きサービスに依存するシナリオが存在する場合があります。 詳細については、「 .NET の依存関係の挿入: サービスの有効期間」を参照してください。

このチュートリアルでは、以下の内容を学習します。

ヒント

すべての ".NET のワーカー" サンプル ソース コードは、 サンプル ブラウザー でダウンロードできます。 詳細については、「コードサンプルを閲覧: .NET のワーカー」を参照してください。

[前提条件]

新しいプロジェクトを作成する

Visual Studio で新しい Worker Service プロジェクトを作成するには、 ファイル>New>Project...を選択します。[ 新しいプロジェクトの作成 ] ダイアログで"Worker Service" を検索し、Worker Service テンプレートを選択します。 .NET CLI を使用する場合は、作業ディレクトリでお気に入りのターミナルを開きます。 dotnet new コマンドを実行し、<Project.Name>を目的のプロジェクト名に置き換えます。

dotnet new worker --name <Project.Name>

.NET CLI の新しい worker サービス プロジェクト コマンドの詳細については、「 dotnet new worker」を参照してください。

ヒント

Visual Studio Code を使用している場合は、統合ターミナルから .NET CLI コマンドを実行できます。 詳細については、「 Visual Studio Code: 統合ターミナル」を参照してください。

スコープ付きサービスを作成する

内でBackgroundServiceを使用するには、IServiceScopeFactory.CreateScope() API を使用してスコープを作成します。 既定では、ホステッド サービスのスコープは作成されません。 スコープ付きバックグラウンド サービスには、バックグラウンド タスクのロジックが含まれています。

namespace App.ScopedService;

public interface IScopedProcessingService
{
    Task DoWorkAsync(CancellationToken stoppingToken);
}

上記のインターフェイスは、1 つの DoWorkAsync メソッドを定義します。 DefaultScopedProcessingService.csという名前の新しいクラスに実装を行います。

namespace App.ScopedService;

public sealed class DefaultScopedProcessingService(
    ILogger<DefaultScopedProcessingService> logger) : IScopedProcessingService
{
    private readonly string _instanceId = Guid.NewGuid().ToString();

    public Task DoWorkAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation(
            "{ServiceName} doing work, instance ID: {Id}",
            nameof(DefaultScopedProcessingService),
            _instanceId);

        return Task.CompletedTask;
    }
}
  • ILoggerは、プライマリ コンストラクターを使用してサービスに挿入されます。
  • DoWorkAsync メソッドはTaskを返し、CancellationTokenを受け入れます。
    • このメソッドはインスタンス識別子をログに記録します。 _instanceId は、クラスがインスタンス化されるたびに割り当てられます。

Worker クラスを書き換える

既存の Worker クラスを次の C# コードに置き換え、ファイルの名前を ScopedBackgroundService.cs に変更します。

namespace App.ScopedService;

public sealed class ScopedBackgroundService(
    IServiceScopeFactory serviceScopeFactory,
    ILogger<ScopedBackgroundService> logger) : BackgroundService
{
    private const string ClassName = nameof(ScopedBackgroundService);

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation(
            "{Name} is running.", ClassName);

        while (!stoppingToken.IsCancellationRequested)
        {
            using IServiceScope scope = serviceScopeFactory.CreateScope();

            IScopedProcessingService scopedProcessingService =
                scope.ServiceProvider.GetRequiredService<IScopedProcessingService>();

            await scopedProcessingService.DoWorkAsync(stoppingToken);

            await Task.Delay(10_000, stoppingToken);
        }
    }

    public override async Task StopAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation(
            "{Name} is stopping.", ClassName);

        await base.StopAsync(stoppingToken);
    }
}

上記のコードでは、 stoppingToken は取り消されませんが、スコープの作成には IServiceScopeFactory が使用されます。 IServiceScopeから、IScopedProcessingServiceが解決されます。 DoWorkAsync メソッドが待機され、stoppingTokenがメソッドに渡されます。 最後に、実行が 10 秒間遅延され、ループが続行されます。 DoWorkAsync メソッドが呼び出されるたびに、DefaultScopedProcessingServiceの新しいインスタンスが作成され、インスタンス識別子がログに記録されます。

テンプレートProgram.csファイル 内容を次の C# コードに置き換えます。

using App.ScopedService;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<ScopedBackgroundService>();
builder.Services.AddScoped<IScopedProcessingService, DefaultScopedProcessingService>();

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

サービスは (Program.cs) に登録されます。 ホステッド サービスは、 AddHostedService 拡張メソッドに登録されます。

サービスの登録の詳細については、「 .NET での依存関係の挿入」を参照してください。

サービス機能を確認する

Visual Studio からアプリケーションを実行するには、 F5 キーを押すか、[ デバッグ>デバッグの開始 ] メニュー オプションを選択します。 .NET CLI を使用している場合は、作業ディレクトリから dotnet run コマンドを実行します。

dotnet run

.NET CLI 実行コマンドの詳細については、「 dotnet run」を参照してください。

アプリケーションを少し実行して、 DoWorkAsyncの呼び出しをいくつか生成し、新しいインスタンス識別子をログに記録します。 次のログのような出力が表示されます。

info: App.ScopedService.ScopedBackgroundService[0]
      ScopedBackgroundService is running.
info: App.ScopedService.DefaultScopedProcessingService[0]
      DefaultScopedProcessingService doing work, instance ID: 8986a86f-b444-4139-b9ea-587daae4a6dd
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: .\scoped-service
info: App.ScopedService.DefaultScopedProcessingService[0]
      DefaultScopedProcessingService doing work, instance ID: 07a4a760-8e5a-4c0a-9e73-fcb2f93157d3
info: App.ScopedService.DefaultScopedProcessingService[0]
      DefaultScopedProcessingService doing work, instance ID: c847f432-acca-47ee-8720-1030859ce354
info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...
info: App.ScopedService.ScopedBackgroundService[0]
      ScopedBackgroundService is stopping.

Visual Studio 内からアプリケーションを実行する場合は、[ デバッグ>ストップ デバッグ...] を選択します。または、コンソール ウィンドウから Ctrl + C を選択してキャンセルを通知します。

こちらも参照ください