Within a WPF application I have configured a hosted service to perform specific activity in background (Followed this article). This is how hosted service is configured in App.xaml.cs.
public App()
{
var environmentName = Environment.GetEnvironmentVariable("HEALTHBOOSTER_ENVIRONMENT") ?? "Development";
IConfigurationRoot configuration = SetupConfiguration(environmentName);
ConfigureLogger(configuration);
_host = Host.CreateDefaultBuilder()
.UseSerilog()
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>()
.AddOptions()
.AddSingleton<IMailSender, MailSender>()
.AddSingleton<ITimeTracker, TimeTracker>()
.AddSingleton<NotificationViewModel, NotificationViewModel>()
.AddTransient<NotificationWindow, NotificationWindow>()
.Configure<AppSettings>(configuration.GetSection("AppSettings"));
}).Build();
AssemblyLoadContext.Default.Unloading += Default_Unloading;
Console.CancelKeyPress += Console_CancelKeyPress;
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
}
And started on startup
/// <summary>
/// Handles statup event
/// </summary>
/// <param name="e"></param>
protected override async void OnStartup(StartupEventArgs e)
{
try
{
Log.Debug("Starting the application");
await _host.StartAsync(_cancellationTokenSource.Token);
base.OnStartup(e);
}
catch (Exception ex)
{
Log.Error(ex, "Failed to start application");
await StopAsync();
}
}
Now I want to stop the hosted service when the system goes to sleep and restart the service when the system resumes. I tried this
/// <summary>
/// Handles system suspend and resume events
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
{
switch (e.Mode)
{
case PowerModes.Resume:
Log.Warning("System is resuming. Restarting the host");
try
{
_cancellationTokenSource = new CancellationTokenSource();
await _host.StartAsync(_cancellationTokenSource.Token);
}
catch (Exception ex)
{
Log.Error(ex, $"{ex.Message}");
}
break;
case PowerModes.Suspend:
Log.Warning("System is suspending. Canceling the activity");
_cancellationTokenSource.Cancel();
await _host.StopAsync(_cancellationTokenSource.Token);
break;
}
}
Stopping the host is working fine But when the host is restarted, I am getting 'System.OperationCanceledException
'. As per my understanding hosted service lifetime is independent of application lifetime. Is my understanding wrong?
This question- ASP.NET Core IHostedService manual start/stop/pause(?) is similar but the answer is to pause and restart the service based on configuration which seems like a hack so I am looking for a standard way.
Any thoughts?