Фоновая задача приложения UWP останавливается, когда мышь / клавиатура отключены - PullRequest
1 голос
/ 19 марта 2019

У меня есть приложение UWP, которое должно работать как информационный дисплей, который должен работать круглосуточно в полноэкранном режиме.У меня есть фоновая задача, которая дозирует некоторые запросы на отдых, анализирует результат и передает его обратно в пользовательский интерфейс.Он работает как задумано.

НО!

Я хочу запустить это на моей системе, которое следует использовать, а затем отсоединить клавиатуру и мышь и уйти.Проблема в том, что когда я делаю это, фоновая задача не запускается.

Он может работать в течение нескольких дней, пока мышь / клавиатура подключены, но в ту же секунду, как я их отключаю, фоновая задача не выполняется.

Обрабатывает ли 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 просто анализирует сгенерированный файл и представляет его в графическом интерфейсе.

Я вижу в журналах, что строка «Триггерная выборка данных» появляется неоднократно, но когда строка «Фоновая задача завершена»"в моих журналах печатаются стопы.

...