Goal
doent worker serviceでBackgroundServiceから予期せぬエラーがスローされたときの挙動を理解して、ゾンビ化しないようにしたい。
.NET 6以前の挙動
BackgroundServiceからスローされた例外は、Hostサービスに無視されていた。そのため、予期せぬエラーが発生した場合、BackgroundServiceはKillされるが、Hostサービスは何事もないように動き続けるふるまいを見せた。
これにより、あたかも正常に動作を続けているように見えて、実は何もしていないという状態が作り出されていた。=Worker serviceのゾンビ化。
.NET 6移行の挙動
BackgroundServiceで予期せぬエラーが発生した場合のHostサービスのふるまいを定義するための列挙型が新設された。
BackgroundServiceExceptionBehavior
この列挙型には、2つの定義がある。
- Ignore
- StopHost (Default)
このうち、Ignoreは、.NET 6以前の挙動と同じふるまいになるように定義するものである。
もう一つのStopHostは、同様の現象が発生したとき、Hostサービス自体を安全に停止するふるまいを定義するもので、.NET 6以降では、デフォルトのふるまいである。
このふるまいの設定は、ServiceのConfigureをするときに設定することができる。
IHost host = Host.CreateDefaultBuilder(args) .ConfigureServices(services => { services.AddHostedService<Worker>(); services.Configure<HostOptions>(HostOptions => { HostOptions.BackgroundServiceExceptionBehavior = BackgroundServiceExceptionBehavior.Ignore; }); }) .Build();
例
二つのBackgroundServiceを定義したとき。Worker Aから予期せぬエラーがスローされた場合。
Ignoreの場合
Worker AはKillされ、その後は何もしない。一方、Worker Bは、そのまま実行を続ける。
StopHostの場合
HostサービスがWorker Aのエラーを検知し、Hostサービスを停止する。この時、ほかのサービスには、cancellationTokenが発行されて順次停止する。