IHostedService
.NET Core 2.1에서 추가된 IHostedService은 개발자에게 관리되는 실행시간에서 백그라운드 서비스들을 실행할 수 있도록 해준다.
이 기능은 최소한의 구현만을 사용이 가능합니다.
public interface IHostedService
{
Task StartAsync(CancellationToken cancellationToken);
Task StopAsync(CancellationToken cancellationToken);
}
.NET Core의 의존성 주입을 해줍니다. 간단하게 구현이 가능하다!
var hostBuilder = new HostBuilder()
.ConfigureServices(services =>
services.AddHostedService<WorkerService>());
실사용 예
IHostedService를 사용한 일반적인 사용 패턴을 살펴보면
- 시간제한 백그라운드 작업
- 범위가 정해진 서비스 처리
- 백그라운드 큐
IHostedService를 통해서 아래와 같은 장기 실행되는 백그라운드 서비스를 등록하려고 했지만
public override async Task StartAsync(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
//Do Something
}
}
위와 같은 구현은 서비스를 멈추고 나머지 모든 것을 정지시킬 것이다. 처음에는 IHostedService가 알아서 백그라운드로 실행돼서 StartAsync 함수에 등록하기만 하면 잘 작동될 거라고 예상했는데 아니었다.
IHostedService는 단기로 실행되는 백그라운드 실행으로 제한되어 있다.
BackgroundService
지속적으로 실행되야하는 작업을 위해서 IHostedService를 상속받는 BackgroundService를 구현할 필요가 있다.
해당 타입의 ExecuteAsync 메서드를 Override 해준다.
public class WorkerHostedService : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stopToken)
{
//Do your preparation (e.g. Start code) here
while (!stopToken.IsCancellationRequested)
{
await DoSomethingAsync();
}
//Do your cleanup (e.g. Stop code) here
}
}
(해당 메시지가 뜨지 않았다면 애플리케이션이 블록 되었다는 뜻이다. 코드를 다시 살펴보도록 하자.)
아래 코드에서 보듯 BackgroundService를 실제로 루프를 돌리기 위해서 다른 작업을 생성한다.
public abstract class BackgroundService : IHostedService, IDisposable
{
private Task _executingTask;
private readonly CancellationTokenSource _stoppingCts = new CancellationTokenSource();
protected abstract Task ExecuteAsync(CancellationToken stoppingToken);
public virtual Task StartAsync(CancellationToken cancellationToken)
{
// Store the task we're executing
_executingTask = ExecuteAsync(_stoppingCts.Token);
// If the task is completed then return it, this will bubble cancellation and failure to the caller
if (_executingTask.IsCompleted)
{
return _executingTask;
}
// Otherwise it's running
return Task.CompletedTask;
}
public virtual async Task StopAsync(CancellationToken cancellationToken)
{
// Stop called without start
if (_executingTask == null)
{
return;
}
try
{
// Signal cancellation to the executing method
_stoppingCts.Cancel();
}
finally
{
// Wait until the task completes or the stop token triggers
await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken));
}
}
public virtual void Dispose()
{
_stoppingCts.Cancel();
}
}
Reference
'프로그래밍 > C#' 카테고리의 다른 글
C# 익명 타입 (Anonymous Type) (10) | 2023.06.19 |
---|---|
C# List에서 HashSet으로 변환하기 (26) | 2023.06.15 |
예제로 복습하는 C# 쓰레드 생성 (27) | 2023.06.01 |
읽기 / 쓰기 프로퍼티(Property) 선언 및 사용 방법 (54) | 2023.05.31 |
C# nameof Expression (22) | 2023.05.26 |
댓글