我有一个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每30秒由DispatcherTimer触发一次。触发的事件如下所示:
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中。
我在日志中看到重复出现了字符串“已触发的数据提取”,但是当字符串“背景任务已完成”停止打印在我的日志中时。