如何禁用UWP App暂停?

时间:2017-11-16 21:51:56

标签: c# uwp

我正在使用C#为Windows 10开发一个仅在桌面计算机上运行的UWP应用程序,目标是平台版本10.0.14393.0。由于业务需求,应用程序生命周期必须像传统的Win32应用程序一样。

因此,我按照this article的建议来请求ExtendedExecutionSession ExtendedExecutionReason.Unspecified。我还将Windows配置为永不休眠,从不休眠。

但是,在极少数情况下,Windows将撤销原因为SystemPolicy的扩展执行会话,然后继续暂停UWP应用程序。

两个问题:

  1. 如何获取有关导致Windows撤销扩展执行会话的更多信息(系统日志?事件日志?)?
  2. 如何摆脱这些罕见的暂停情况,以便UWP应用程序生命周期的行为与Win32应用程序完全相同(即,在用户明确停止运行之前保持运行)?
  3. 谢谢!

5 个答案:

答案 0 :(得分:3)

ExtendedExecutionSession

ExtendedExecutionReason.Unspecified受资源消耗的多项限制。由于您的测试设备没有电池,因此应用程序暂停的最可能原因是其内存使用率很高。您可以尝试根据内存消耗优化应用,并根据文档建议使用Memory Management APIs,但这并不能保证您的应用永远不会被暂停。

如果您的应用针对的是商业领域,那么您可以考虑使用功能更强大的ExtendedExecutionForegroundSession代替ExtendedExecutionSession。这可能是您问题的完美解决方案。但它是一种受限制的功能,这意味着使用它的应用程序不允许进入Windows应用商店 - 仅限于Windows Store for Business。您还需要在清单中手动声明extendedExecutionUnconstrained功能(请参阅Special and restricted capabilities section of documentation)以利用API。

或者,您可以使用阻止应用程序长时间暂停的黑客攻击:

  1. 使用 App services 与Win32应用进行通信,建议 pnp0a03

  2. 使用 Background Media Playback 在循环中无限播放静音音频样本(即使用户手动停止或其他应用暂停播放自己的背景音频) ,您的应用程序可以跟踪它并自动重新开始播放)。

答案 1 :(得分:1)

我记得以前的SO帖子 - 他的问题是:当我使用App服务与Win32应用程序通信时,它会阻止应用程序进入暂停状态。 我已经成功地使用帖子中提到的示例应用程序重新创建了该问题。

我现在不是预期的行为,但它可能有助于解决您的情况。

UWP application not going to suspend state

答案 2 :(得分:0)

使用Visual Studio调试模式运行应用程序,应用程序永远不会进入挂起状态。它被Visual Studio保持唤醒。

啊,这只是个玩笑。

我认为不幸的是,您所期望的行为与UWP的设计原则相矛盾。

系统保留在某些“叛逃”后暂停后台应用程序的权利。如果您请求延长执行会话,您还必须为撤销做准备,连接到墙上电源不会让应用程序永远运行。

选项1适用于桌面应用,但这可能不是一种选择。如果你得到这个要求,因为像UWP这样的用户却不喜欢“暂停”的想法(暂停了什么?),恐怕你无法满足这个要求。

选项2是......是否有任何真正的任务必须保持运行,即使应用程序切换到后台?如果任务需要定期运行,例如检查邮件帐户的收件箱,则可以使用某种计时器触发的后台任务。

选项3:考虑自助服务终端模式,设备上只允许运行一个应用程序,因此无法切换到后台并暂停使用。

答案 3 :(得分:0)

我试图解决这个问题已经好几天了,但之后发现了这个链接。非常好的解释和解决方案,最重要的是..易于理解。 您需要将代码放在app.xaml.cs中,并编辑包清单文件。 您还需要在app.xaml.cs

中使用以下指令

使用Windows.ApplicationModel.ExtendedExecution.Foreground; 使用System.Threading.Tasks;

non-suspending-uwp

答案 4 :(得分:0)

根据this article in MSDN magazine,您还可以使用后台任务使应用程序保持活动状态。这篇文章声称,后台任务比扩展会话方法更可取。

BackgroundTask实现

public sealed class TimerTask : IBackgroundTask
{
  public void Run(IBackgroundTaskInstance taskInstance)
  {
    var deferral = taskInstance.GetDeferral();
    taskInstance.Canceled += TaskInstance_Canceled;
    await ShowToastAsync("Hello from Background Task");
    deferral.Complete();
  }
  private void TaskInstance_Canceled(IBackgroundTaskInstance sender,
    BackgroundTaskCancellationReason reason)
  {
    // Handle cancellation
    deferral.Complete();
  }
}

在应用程序清单中,还必须注册后台任务。该注册将告诉Windows触发器类型,任务的入口点和可执行主机,如下所示:

<Extensions>
  <Extension Category="windows.backgroundTasks" EntryPoint="BackgroundTasks.TimerTask">
    <BackgroundTasks>
      <Task Type="timer" />
    </BackgroundTasks>
  </Extension>

后台任务注册

private void RegisterBackgroundTasks()
{
  BackgroundTaskBuilder builder = new BackgroundTaskBuilder();
  builder.Name = "Background Test Class";
  builder.TaskEntryPoint = "BackgroundTaskLibrary.TestClass";
  IBackgroundTrigger trigger = new TimeTrigger(30, true);
  builder.SetTrigger(trigger);
  IBackgroundCondition condition =
    new SystemCondition(SystemConditionType.InternetAvailable);
  builder.AddCondition(condition);
  IBackgroundTaskRegistration task = builder.Register();
  task.Progress += new BackgroundTaskProgressEventHandler(task_Progress);
  task.Completed += new BackgroundTaskCompletedEventHandler(task_Completed);
}