BackgroundService 내에서 범위가 지정된 서비스 사용

AddHostedService 확장 메서드를 사용하여 IHostedService 구현을 등록하면 서비스가 싱글톤으로 등록됩니다. 범위가 지정된 서비스를 사용하려는 시나리오가 있을 수 있습니다. 자세한 내용은 .NET에서 종속성 주입: 서비스 수명을 참조하세요.

이 자습서에서는 다음을 하는 방법을 알아볼 수 있습니다.

모든 ‘.NET의 작업자’ 예제 소스 코드는 샘플 브라우저에서 다운로드할 수 있습니다. 자세한 내용은 코드 샘플 찾아보기: .NET의 작업자를 참조하세요.

필수 조건

새 프로젝트 만들기

Visual Studio를 사용하여 새 Worker Service 프로젝트를 만들려면 파일>새로 만들기>Project...를 선택합니다. 새 프로젝트 만들기 대화 상자에서 "Worker Service"를 검색하고 Worker Service 템플릿을 선택합니다. .NET CLI를 사용하려면 작업 디렉터리에서 즐겨찾는 터미널을 엽니다. dotnet new 명령을 실행하고 <Project.Name>을 원하는 프로젝트 이름으로 바꿉니다.

dotnet new worker --name <Project.Name>

.NET CLI 새 작업자 서비스 프로젝트 명령에 대한 자세한 내용은 dotnet 새 작업자를 참조하세요.

Visual Studio Code를 사용하는 경우 통합 터미널에서 .NET CLI 명령을 실행할 수 있습니다. 자세한 내용은 Visual Studio Code: 통합 터미널을 참조하세요.

범위가 지정된 서비스 만들기

BackgroundService 내에서 범위가 지정된 서비스를 사용하려면 범위를 만듭니다. 기본적으로 호스팅되는 서비스에 대한 범위는 생성되지 않습니다. 범위가 지정된 백그라운드 서비스에는 백그라운드 작업의 논리가 포함됩니다.

namespace App.ScopedService;

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

앞의 인터페이스는 단일 DoWorkAsync 메서드를 정의합니다. 기본 구현을 정의하려면 다음을 수행합니다.

  • 서비스는 비동기입니다. DoWorkAsync 메서드는 Task를 반환합니다. 데모용으로 DoWorkAsync 메서드에서 10초의 지연이 있습니다.
  • ILogger가 서비스에 삽입됩니다.
namespace App.ScopedService;

public sealed class DefaultScopedProcessingService(
    ILogger<DefaultScopedProcessingService> logger) : IScopedProcessingService
{
    private int _executionCount;

    public async Task DoWorkAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            ++ _executionCount;

            logger.LogInformation(
                "{ServiceName} working, execution count: {Count}",
                nameof(DefaultScopedProcessingService),
                _executionCount);

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

호스팅되는 서비스는 범위가 지정된 백그라운드 서비스를 해결하여 DoWorkAsync 메서드를 호출하는 범위를 만듭니다. DoWorkAsyncExecuteAsync에서 대기하고 있는 Task를 반환합니다.

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

        await DoWorkAsync(stoppingToken);
    }

    private async Task DoWorkAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation(
            "{Name} is working.", ClassName);

        using (IServiceScope scope = serviceScopeFactory.CreateScope())
        {
            IScopedProcessingService scopedProcessingService =
                scope.ServiceProvider.GetRequiredService<IScopedProcessingService>();

            await scopedProcessingService.DoWorkAsync(stoppingToken);
        }
    }

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

        await base.StopAsync(stoppingToken);
    }
}

위의 코드에서는 명시적 범위가 생성되고 종속성 주입 서비스 범위 팩터리에서 IScopedProcessingService 구현이 확인됩니다. 확인된 서비스 인스턴스의 범위가 지정되고 DoWorkAsync 메서드가 대기됩니다.

템플릿 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 실행을 참조하세요.

애플리케이션을 실행하여 여러 실행 횟수 증가를 생성할 수 있습니다. 다음과 유사한 출력이 표시됩니다.

info: App.ScopedService.ScopedBackgroundService[0]
      ScopedBackgroundService is running.
info: App.ScopedService.ScopedBackgroundService[0]
      ScopedBackgroundService is working.
info: App.ScopedService.DefaultScopedProcessingService[0]
      DefaultScopedProcessingService working, execution count: 1
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 working, execution count: 2
info: App.ScopedService.DefaultScopedProcessingService[0]
      DefaultScopedProcessingService working, execution count: 3
info: App.ScopedService.DefaultScopedProcessingService[0]
      DefaultScopedProcessingService working, execution count: 4
info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...
info: App.ScopedService.ScopedBackgroundService[0]
      ScopedBackgroundService is stopping.

Visual Studio 내에서 애플리케이션을 실행하는 경우 디버그>디버깅 중지...를 선택합니다. 또는 콘솔 창에서 Ctrl + C를 선택하여 취소 신호를 보냅니다.

참고 항목