在 WPF 应用程序中,我配置了一个托管服务以在后台执行特定活动(按照本文)。这是在 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;
}
并在启动时开始
/// <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();
}
}
现在我想在系统进入睡眠状态时停止托管服务,并在系统恢复时重新启动服务。我试过这个
/// <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;
}
}
停止主机工作正常但是当主机重新启动时,我得到' System.OperationCanceledException
'。根据我的理解,托管服务的生命周期独立于应用程序的生命周期。我的理解错了吗?
这个问题- ASP.NET Core IHostedService 手动启动/停止/暂停(?)是相似的,但答案是根据配置暂停和重新启动服务,这似乎是一个黑客,所以我正在寻找一种标准方式。
有什么想法吗?