【发布时间】:2020-04-29 07:13:17
【问题描述】:
在 WPF 应用程序中,我已配置托管服务以在后台执行特定活动(关注 this article)。 这是在 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 manual start/stop/pause(?) 类似,但答案是根据配置暂停并重新启动服务,这似乎是一种黑客行为,所以我正在寻找一种标准方法。
有什么想法吗?
【问题讨论】:
-
将调用
Host.CreateDefaultBuilder()并初始化主机的代码移动到OnStartup方法,以便在每次要重新启动它时创建一个新主机。你会发现一个例子here。 -
我相信主机被设计为只运行一次。不过,您也许可以停止和启动您的后台服务。
Worker有自己的启动和停止(大部分)独立于主机启动和停止。
标签: c# wpf .net-core task ihostedservice