public async Task RunAsync() { Task backgroundService = null; CancellationTokenSource cts = null; bool isFirstTime = true; try { while (!_ApplicationLifetimeManager.GracefulTerminationCancellationToken.IsCancellationRequested) { bool featureToggleValue = _FeatureToggle.IsEnabled; if (featureToggleValue && (backgroundService is null)) { if (!isFirstTime) { _Logger.LogDebug( $"Starting background service {_TypeHelper.NameOf(_BackgroundService.GetType())} due to configuration changes"); } cts = new CancellationTokenSource(); backgroundService = RunBackgroundService(cts.Token); isFirstTime = false; } else if (!featureToggleValue && !(backgroundService is null)) { cts.Cancel(); await backgroundService; backgroundService = null; cts.Dispose(); cts = null; _Logger.LogDebug( $"Stopped background service {_TypeHelper.NameOf(_BackgroundService.GetType())} due to configuration changes"); } // toggle status await Task.Delay(10000, _ApplicationLifetimeManager.GracefulTerminationCancellationToken); } if (backgroundService != null) { cts.Cancel(); await backgroundService; _Logger.LogDebug( $"Starting background service {_TypeHelper.NameOf(_BackgroundService.GetType())} due to application termination"); } } finally { cts?.Dispose(); } }
public static void ServiceStopped(this ILogger logger, IBackgroundService service, TimeSpan elapsed) { _serviceStopped( logger, service.GetType().GetDisplayName(), (long)elapsed.TotalMilliseconds); }
public static void ServiceStopFailed(this ILogger logger, IBackgroundService service, TimeSpan elapsed, Exception exception) { _serviceStopFailed( logger, service.GetType().GetDisplayName(), (long)elapsed.TotalMilliseconds, exception: exception); }
public async Task Execute(CancellationToken cancellationToken) { int restartCount = 0; while (true) { try { if (restartCount > 0) { _Logger.LogDebug($"restart-attempt #{restartCount} for background service {_TypeHelper.NameOf(_DecoratedService.GetType())}"); } await _DecoratedService.Execute(cancellationToken); if (restartCount > 0) { _Logger.LogDebug($"background service {_TypeHelper.NameOf(_DecoratedService.GetType())} terminated normally"); } return; } catch (TaskCanceledException) { throw; } catch (Exception ex) { _Logger.LogException(ex); restartCount++; TimeSpan restartDelay = GetRestartDelay(restartCount); _Logger.LogVerbose( $"background service {_TypeHelper.NameOf(_DecoratedService.GetType())} terminated due to an exception, restarting it in {restartDelay.Humanize()}"); await Task.Delay(restartDelay, cancellationToken).NotNull(); } } }
public static void ServiceStopping(this ILogger logger, IBackgroundService service) { _serviceStopping(logger, service.GetType().GetDisplayName()); }