单进程 UWP 场景中的 TimeTrigger 未触发

TimeTrigger not firing in Single-Process UWP Scenario

最近几天我一直在用头撞显示器。我正在为 Windows 商店(目标 14393)开发一个 UWP 应用程序,我正在为 MVVM / IoC 使用 Prism/Unity 框架。

由于更新动态磁贴所需的数据存储在实现存储库模式的 class 中,并且所有内容都通过 Unity 进行管理,因此我没有为后台执行创建单独的进程,因此甚至简化了整个BGTask注册流程。

实际BGTask注册码如下:

var servicingTaskAlreadyRegistered = false;
var tileUpdaterTaskAlreadyRegistered = false;

foreach (var t in BackgroundTaskRegistration.AllTasks)
{
    if (t.Value.Name == Constants.BgTileUpdaterTaskName)
        tileUpdaterTaskAlreadyRegistered = true;
    else if (t.Value.Name.Equals(Constants.BgServicingTaskName))
        servicingTaskAlreadyRegistered = true;
}

var reqAccess = await BackgroundExecutionManager.RequestAccessAsync();
if (reqAccess == BackgroundAccessStatus.Denied ||
    reqAccess == BackgroundAccessStatus.DeniedBySystemPolicy ||
    reqAccess == BackgroundAccessStatus.DeniedByUser ||
    reqAccess == BackgroundAccessStatus.Unspecified)
    return false;

if (!servicingTaskAlreadyRegistered)
{
    var servicingTaskBuilder = new BackgroundTaskBuilder();
    servicingTaskBuilder.Name = Constants.BgServicingTaskName;
    servicingTaskBuilder.SetTrigger(new SystemTrigger(SystemTriggerType.ServicingComplete, false));
    servicingTaskBuilder.Register();
}

if (tileUpdaterTaskAlreadyRegistered)
    return true;

var builder = new BackgroundTaskBuilder();
builder.Name = Constants.BgTileUpdaterTaskName;
builder.SetTrigger(new TimeTrigger(TileUpdateFrequencyMinutes, false));
//builder.SetTrigger(new MaintenanceTrigger(TileUpdateFrequencyMinutes, false));
builder.IsNetworkRequested = true;

builder.Register();

注册成功完成。在 PowerShell 中执行 Get-AppBackgroundTask 会显示这两个任务,这是应该的。但是,TimeTrigger 永远不会触发。用 MaintenanceTrigger 交换 TimeTrigger 解决了这个问题,尽管智能手机需要插入充电器,这是不可接受的解决方法。

通过 VisualStudio 或 PowerShell (Start-AppBackgroundTask -TaskID) 强制任务 运行 正确执行并且磁贴得到更新。

您还有其他有用的提示要分享吗?

编辑 12/01/2017 我创建了一个 Repro,其中包含一个 Visual Studio 解决方案和两个项目:

这解释了我遇到问题的原因:Unity 未初始化、我无法通过存储库检索数据、应用程序崩溃和 GG。

现在我只需要了解为什么 Unity 在 OnBackgroundActivated 方法中不可用。快到了!

复制:https://github.com/eraser85/LiveTileTestRepro

代码对我来说看起来不错,我在这里尝试更改的唯一事情是 IsNetwokRequested 属性 和 TimeTrigger 频率值的使用,你确定吗您使用的 constant/variable 是否大于或等于 15?

这是一个示例:

BackgroundTaskBuilder builder = new BackgroundTaskBuilder { Name = "YourBgTaskName" };
builder.SetTrigger(new TimeTrigger(15, false));
builder.AddCondition(new SystemCondition(SystemConditionType.InternetAvailable));
builder.Register();

好的,经过更多的测试,我终于想出了一个解决方案。

如前所述,问题源于 Prism:基本上,当由 OS 启动并通过 OnBackgroundActivated() 进入时,IoC 容器未被初始化。

解决方案,即使看起来 hack-ish,实际上是完全可行和正确的(恕我直言!)。在你的 OnBackgroundActivated() 中,就像从头开始一样初始化所有内容(查看 Prism's Source 了解实现细节):在我的具体情况下,我只是调用了 CreateAndConfigureContainer() 和 re-registered 一切我输入了 OnInitializeAsync()(例如回购、服务..)。

opened an issue 与开发人员一起工作。也许解决方案已经在路上,但与此同时应该这样做。