c# - UWP 应用程序后台任务在鼠标/键盘断开连接时停止
问题描述
我有一个 UWP 应用程序,它应该作为一个信息显示,应该在全屏模式下 24/7 运行。我有一个后台任务,它处理一些休息请求并解析结果并将其传递回 UI。它按预期工作。
但!
我想在我应该使用的系统上启动它,然后断开键盘和鼠标并走开。问题是当我这样做时,后台任务不会运行。
只要插入鼠标/键盘,它就可以运行数天,但在我断开它们的那一刻,后台任务就不会执行。
Windows 是否像应用失去焦点并随后暂停所有后台工作一样处理鼠标/键盘断开连接?
编辑:
这就是我创建后台任务的方式:
private async void MainPage_OnLoaded(object _sender, RoutedEventArgs _e)
{
var registration = BackgroundTaskRegistration.AllTasks.SingleOrDefault(_t => _t.Value.Name == BACKGROUND_TASK_NAME).Value;
if (registration != null)
{
backgroundTask = (BackgroundTaskRegistration)registration;
Logger.Information("Found background task with {ID} in application settings and found it registered, reusing it", backgroundTask.TaskId);
}
else
{
var backgroundAccessStatus = await BackgroundExecutionManager.RequestAccessAsync();
Logger.Information("backGroundAccessStatus is {Status}", backgroundAccessStatus);
if (backgroundAccessStatus == BackgroundAccessStatus.DeniedBySystemPolicy ||
backgroundAccessStatus == BackgroundAccessStatus.DeniedByUser)
{
Logger.Error("Cannot create background task");
return;
}
var builder = new BackgroundTaskBuilder
{
Name = BACKGROUND_TASK_NAME,
TaskEntryPoint = TASK_ENTRY_POINT
};
builder.SetTrigger(fetchTrigger);
backgroundTask = builder.Register();
Logger.Information("Created a new Background task with id: {ID}", backgroundTask.TaskId);
}
backgroundTask.Completed += BackgroundFetcher_Completed;
}
我的 ApplicationTrigger 由 DispatcherTimer 每 30 秒触发一次。触发的事件如下所示:
private async void FetchTimerOnTick(object _sender, object _e)
{
var triggerResult = await fetchTrigger.RequestAsync();
switch (triggerResult)
{
case ApplicationTriggerResult.Allowed:
Logger.Information("Triggered fetching of data");
break;
case ApplicationTriggerResult.CurrentlyRunning:
Logger.Information("Fetch task not complete yet. checking again in 30 sec");
break;
case ApplicationTriggerResult.DisabledByPolicy:
Logger.Error("Fetch trigger disabled by policy");
return;
case ApplicationTriggerResult.UnknownError:
Logger.Error("Fetch trigger had an unknown error");
return;
}
}
我的 BackgroundTask 运行如下所示:
public void Run(IBackgroundTaskInstance taskInstance)
{
Logger.Information("Background fetcher started");
var deferral = taskInstance.GetDeferral();
var timetableRequestTask = timeTablesModel.FetchTimeTables();
var weatherRequestTask = weatherModel.FetchWeather();
var newsRequestTask = newsTickerModel.FetchNews();
Task.WaitAll(timetableRequestTask, weatherRequestTask, newsRequestTask);
var fetchedData = new FetchedData
{
TimeTablesResponse = (TimeTablesResponse)timetableRequestTask.Result,
WeatherUpdate = weatherRequestTask.Result,
NewsResponse = (NewsResponse)newsRequestTask.Result
};
var path = $"{Path.GetTempPath()}BackgroundFetcherResultFile.json";
using (var streamWriter = File.CreateText(path))
{
using (var jsonWriter = new JsonTextWriter(streamWriter))
{
var serializer = new JsonSerializer();
serializer.Serialize(jsonWriter, fetchedData);
jsonWriter.Flush();
}
}
Logger.Information("Background fetcher completed");
Task.Delay(TimeSpan.FromSeconds(5)).Wait();
deferral.Complete();
}
backgroundTask.Completed 的事件如下所示:
private async void BackgroundFetcher_Completed(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs args)
{
Logger.Information("Background task completed");
try
{
args.CheckResult();
}
catch (Exception e)
{
Logger.Error(e, "Exception occured in background task");
return;
}
FetchedData fetchedData;
var path = $"{Path.GetTempPath()}BackgroundFetcherResultFile.json";
using (var streamReader = File.OpenText(path))
{
using (var jsonTextReader = new JsonTextReader(streamReader))
{
var serializer = new JsonSerializer();
fetchedData = serializer.Deserialize<FetchedData>(jsonTextReader);
}
}
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
if (fetchedData.TimeTablesResponse != null) timeTables.UpdateUi(fetchedData.TimeTablesResponse);
var currentWeather = fetchedData.WeatherUpdate.CurrentWeather;
var radar = fetchedData.WeatherUpdate.Radar;
var forecast = fetchedData.WeatherUpdate.WeatherForecast;
if (currentWeather != null) weather.UpdateCurrentWeatherUi(currentWeather);
if (radar != null) weather.UpdateRadarUi(radar);
if (forecast != null) weather.UpdateWeatherForecastUi(forecast);
if (fetchedData.NewsResponse != null)
{
news.UpdateNewsArticles(fetchedData.NewsResponse);
}
});
}
Completed 事件只是解析生成的文件并将其呈现在 GUI 中。
我可以在日志中看到字符串“Triggered fetching of data”重复出现,但是当字符串“Background task completed”停止在我的日志中打印时。
解决方案
推荐阅读
- objective-c - 分离由 CGWindowListCopyWindowInfo 返回的真实和虚拟窗口
- javascript - e.pageX 和 pageY 将工具提示放在一个奇怪的区域
- c++ - boost asio tcp socket 1.70 不向后兼容
- php - 无法从 php 执行的 shell 脚本正确挂载加密分区
- python - 在 pandas 中使用字典作为条件
- jmeter - 使用 UDP 的桌面应用程序的性能测试
- c++ - 来自不同翻译单元的 consteval 函数会干扰吗?
- javascript - 如何在不更改现有值的情况下使用相同的名称设置属性
- javascript - vue发送param值,声明发送哪个param
- java - Spring Security 使多个应用程序上的 http 会话无效?