首页 > 解决方案 > 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”停止在我的日志中打印时。

标签: c#uwpbackground-task

解决方案


推荐阅读