다음을 통해 공유


IHostedService 인터페이스 구현

제공된 것 이상으로 한정된 BackgroundService제어가 필요한 경우 사용자 고유 IHostedService의 컨트롤을 구현할 수 있습니다. 인터페이스는 IHostedService .NET의 모든 장기 실행 서비스의 기초입니다. 사용자 정의 구현은 AddHostedService<THostedService>(IServiceCollection) 확장 메서드에 등록됩니다.

이 튜토리얼에서는 다음을 배우게 됩니다:

  • IHostedServiceIAsyncDisposable 인터페이스를 구현합니다.
  • 타이머 기반 서비스를 만듭니다.
  • 종속성 주입 및 로깅을 사용하여 사용자 지정 구현을 등록합니다.

팁 (조언)

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

필수 조건

새 프로젝트 만들기

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

dotnet new worker --name <Project.Name>

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

팁 (조언)

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

타이머 서비스 만들기

타이머 기반 백그라운드 서비스는 클래스를 System.Threading.Timer 사용합니다. 타이머가 DoWork 메서드를 트리거합니다. 서비스 컨테이너가 IHostLifetime.StopAsync(CancellationToken)에서 삭제될 때 IAsyncDisposable.DisposeAsync()에서 타이머가 비활성화되고 삭제됩니다.

템플릿의 Worker 내용을 다음 C# 코드로 바꾸고 파일 이름을 TimerService.cs.

namespace App.TimerHostedService;

public sealed class TimerService(ILogger<TimerService> logger) : IHostedService, IAsyncDisposable
{
    private readonly Task _completedTask = Task.CompletedTask;
    private int _executionCount = 0;
    private Timer? _timer;

    public Task StartAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation("{Service} is running.", nameof(TimerHostedService));
        _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(5));

        return _completedTask;
    }

    private void DoWork(object? state)
    {
        int count = Interlocked.Increment(ref _executionCount);

        logger.LogInformation(
            "{Service} is working, execution count: {Count:#,0}",
            nameof(TimerHostedService),
            count);
    }

    public Task StopAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation(
            "{Service} is stopping.", nameof(TimerHostedService));

        _timer?.Change(Timeout.Infinite, 0);

        return _completedTask;
    }

    public async ValueTask DisposeAsync()
    {
        if (_timer is IAsyncDisposable timer)
        {
            await timer.DisposeAsync();
        }

        _timer = null;
    }
}

중요합니다

Worker 하위 클래스 BackgroundService였습니다. 이제 TimerServiceIHostedServiceIAsyncDisposable 인터페이스를 모두 구현합니다.

TimerServicesealed이며, 자신의 _timer 인스턴스에서 DisposeAsync 호출을 계단식으로 배열합니다. "연계 삭제 패턴"에 대한 자세한 내용은 DisposeAsync 메서드 구현을 참조하세요.

StartAsync 호출되면 타이머가 인스턴스화되어 타이머가 시작됩니다.

팁 (조언)

Timer는 이전에 실행된 DoWork를 마칠 때까지 기다리지 않으므로 제시된 방법이 모든 시나리오에 적합한 것은 아닐 수 있습니다. Interlocked.Increment 는 여러 스레드가 동시에 업데이트 _executionCount 되지 않도록 하는 원자성 작업으로 실행 카운터를 증가시키는 데 사용됩니다.

기존 Program 콘텐츠를 다음 C# 코드로 바꿉니다.

using App.TimerHostedService;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<TimerService>();

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

서비스는 Program.cs에서 AddHostedService 확장 메서드를 사용하여 등록됩니다. 이 메서드는 둘 다 IHostedService 인터페이스를 구현하므로 BackgroundService 서브클래스를 등록할 때 사용하는 것과 동일한 확장 메서드입니다.

서비스 등록에 대한 자세한 내용은 .NET 종속성 주입을 참조하세요.

서비스 기능 확인

Visual Studio에서 애플리케이션을 실행하려면 F5 를 선택하거나 디버그>시작 디버깅 메뉴 옵션을 선택합니다. .NET CLI를 사용하는 경우 작업 디렉터리에서 명령을 실행 dotnet run 합니다.

dotnet run

.NET CLI 실행 명령에 대한 자세한 내용은 dotnet run을 참조하세요.

애플리케이션을 잠시 동안 실행하여 여러 실행 횟수를 증가시키도록 합니다. 다음과 유사한 출력이 표시됩니다.

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

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

참고하십시오

고려해야 할 몇 가지 관련 자습서가 있습니다.