Postpone app suspension with extended execution
通过延续运行(Extended Execution),应用可以在最小化或者锁屏的时候运行。
通常进入幕后(最小化或者锁屏)的时候,App会被挂起,内存会保留但是代码不会运行。但是这不会里面发生,操作系统可以让App在后台运行一段时间再挂起,或者应用可以申请延续运行一段时间,然后才挂起。
调试模式下不会挂起
创建ExtendedExecutionSession来获取更多后台执行时间。ExtendedExecutionSession有几种会话类型:
- Unspecified
- LocationTracking
- SavingData
一次只能申请一个ExtendedExecutionSession。Store不允许App使用ExtendedExecutionForegroundSession或者ExtendedExecutionForegroundReason;
<! – Run while minimized –>
使用ExtendedExecutionSession的时机:
- 任何时刻,只要应用在前台运行
- 当App接收到挂起事件的时候
两种情况下代码相同。但是第一种情况App申请成功之后就不会收到挂起事件了。第二种情况只是推迟了挂起的发生而已,当时间结束时候会被直接挂起。
使用ExtendedExecutionReason.Unspecified来在应用进入幕后之前获取更多在幕后的运行时间。在桌面版本,这可以有效地阻止应用在最小化地时候被挂起。
ExtendedExecutionReason.Unspecified在插电地情况下可以无限运行,在使用电池地情况下可以运行10分钟。
平板或者笔记本可以开启 Allow the app to run background tasks选项(Settings > System > Battery > Battery usage by App),来获取和桌面类似地效果。
在所有地操作系统上,当设备进入Connected Standby,延续运行也会被暂停。在桌面环境下,锁屏是依然可以延续运行,当屏幕熄灭时进入Connected Standby。在XBox情况下,Connected Standby一般需要等待一个小时才会进入。
ExtendedExecutionReason.LocationTracking 跟GeoLocator相关。
使用ExtendedExecutionReason.SavingData来保存尚未保存地数据,而不是其他目的。
ExtendedExecutionReason.SavingData可以在前台、幕后或者即将挂起地时候申请。在挂起前申请ExtendedExecutionReason.SavingData需要注意地是,当用户再次加载该App地时候,需要等待之前地ExtendedExecutionReason.SavingData完成。
针对延续运行,有三种操作:请求,释放,中止。
请求的例子:
var newSession = new ExtendedExecutionSession();
newSession.Reason = ExtendedExecutionReason.Unspecified;
newSession.Revoked += SessionRevoked;
ExtendedExecutionResult result = await newSession.RequestExtensionAsync();
switch (result)
{
case ExtendedExecutionResult.Allowed:
DoLongRunningWork();
break;
default:
case ExtendedExecutionResult.Denied:
DoShortRunningWork();
break;
}
用户设置可能会影响延续运行: 参考Background Activity and Energy Awareness
当延续运行的许可时间截止、或者其他前台任务需要资源的时候,延续运行可能会被释放,App会接受到一个Revoked事件。
在ExtendedExecutionReason.SavingData ,App只有1秒钟时间来在挂起前完成操作。
一个例子:
private async void SessionRevoked(object sender, ExtendedExecutionRevokedEventArgs args)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
switch (args.Reason)
{
case ExtendedExecutionRevokedReason.Resumed:
rootPage.NotifyUser("Extended execution revoked due to returning to foreground.", NotifyType.StatusMessage);
break;
case ExtendedExecutionRevokedReason.SystemPolicy:
rootPage.NotifyUser("Extended execution revoked due to system policy.", NotifyType.StatusMessage);
break;
}
EndExtendedExecution();
});
}
App可以主动中止延续运行。允许系统回收资源,一个例子:
void ClearExtendedExecution(ExtendedExecutionSession session)
{
if (session != null)
{
session.Revoked -= SessionRevoked;
session.Dispose();
session = null;
}
}
在中止延续允许之前,确保所有相关的异步操作都结束了。章节中·举了一个相关的例子。
为了良好使用资源,确保App不使用过多内存Memory Management APIs ,以及确保用户没有对BackgroundExecutionManager.RequestAccessAsync 进行限制
(本篇完)