@Tyler,Cyberherbalist:我很遗憾我不能直接在您的讨论中“添加评论”。我的声誉还是太低了。我没有任何博客可以将其发布到那里并为您提供指向它的链接。我就写在这里,因为我认为值得注意并写在某个地方,所以其他人也可以检查/使用/性能从中获利。
..所以,请原谅我在这里写这篇“题外话”:)
虽然我不知道如何很好地解决问题 - 我的解决方案通常是手动收集导航历史记录堆栈,将其放入 iso,并在激活时恢复并跳转到正确/最后的位置 - 我可以告诉你一些关于墓碑的一些事情。
问题是,如果您的申请是停用,这确实not意味着它已被墓碑化。停用只是意味着您的应用程序被移出屏幕。在 Mango 版本中,您可以点击并按住“后退”设备按钮,查看当前打开的应用程序,然后跳转到任何应用程序。 “激活”是指您的应用程序被唤醒。即使在 WP7 SDK+模拟器的早期版本中,我也从我的应用程序中调用外部媒体播放器,并且我的应用程序几乎从未被物理杀死。停用/激活总是在“暂停”的地方恢复我的应用程序。所有内存中的对象都未受影响。
当设备资源不足时,就会发生逻辑删除,并且必须“终止”一些后台任务以释放内存。我相信当设备的屏保下拉或者设备长时间处于待机状态时也可能会出现这种情况。逻辑删除实际上会杀死您的应用程序,所有内存中的对象都将被销毁/删除等等。唯一能够幸存的就是 AppSettings 和 ISO 存储。墓碑效应肯定会发生ONLY如果您的申请位于停用 state.
那么,您可以看到哪些生命周期?
1)“冻结/待机/失焦”:
- 发射
- ... (在职的)
- 已停用(移至后台)
- ...(保存在内存中,也许进程/线程被冻结,但我怀疑)
- (...)
- 已激活(移至前台,不发生导航)
- ... (在职的)
- Closing
2)“墓碑”:
- 发射
- ... (在职的)
- 已停用(移至后台)
- ...(保存在内存中,也许进程/线程被冻结,但我怀疑)
- ...(被墓碑化,从记忆中删除,一切都被摧毁)
- (...)
- ...(构造干净的应用程序对象)
- 已激活(移至前台)
- 导航(我认为,总是到清单中设置的第一个默认页面,但我现在不确定)
- (在职的)
- Closing
这意味着,墓碑可能有点难以检测,但也意味着,您总是有时间尝试在停用事件处理程序中保持相同的状态。
这也意味着(除非有一些我还不知道的通知服务),检测从墓碑恢复是否依赖的唯一方法是依赖最致命/最不愉快的效果其中:关于清除你的记忆。
想象一个最简单的情况:您的 App 对象有一个属性“private bool _tomb_test”。它可以是任何类型的任何属性/字段。您也可以使用“object ViewModel{get;set}”来实现此目的。
首先要记住的是,NOT在构造函数中设置它,然后执行NOT分配内联默认值。让它漂浮即可。每当新创建 App 对象时,编译器/运行时都会将其设置为默认 false。这就是重点!
now:
- 在 Launched (不是 ctor!!!) 中,设置“_tomb_test = true”
- 在停用状态下,将最低持久状态保存到 ISO
- in activated, check:
- 如果 _tomb_test==false 则意味着您已被墓碑化。你的记忆是干净的,所有的物体都被摧毁了。根据上次写入 ISO 的数据恢复您的状态,然后启动所有作业来重新填充/重新下载/重新加载/重新计算/等应用程序状态的所有其他部分
- 但是,如果 _tomb_test==true,则意味着逻辑删除未发生。你的记忆未受影响。也许只是 GC 启动并收集了死者。所有曾经有生命的物体仍然活着。该应用程序可以免费运行,就像什么都没发生一样。
虽然它看起来很漂亮,但请原谅我这个冗长的免责声明:
我在当前应用程序中成功使用它,100% 成功,但我不能说这是有保证的平台行为。我还没有时间在 MSDN 上挖掘事实。以上所有内容均来自我对 7.0 和 7.1 SDK 版本的观察。
上述方法的一个小问题是relies基于(未经证实?)的假设,内存清除以全有或全无的方式进行。
也就是说,假设所有对象都被清除,或者没有发生清除(当前事实:App 对象被观察到从头开始重新创建,甚至发生初始导航来重新创建 UI。在其他情况下,这两种情况都不会发生)发生)。
对于错误的假设...我无法想象谁以及为什么会决定在 .net 世界中实施部分内存清除。完全清除意味着杀死该应用程序。部分清除意味着销毁 GC 代中的随机活动对象,并让所有剩余的对象保持悬空句柄或空句柄。我无法想象。我没有观察到。因此,我认为这是全有或全无的情况。
顺便提一句。如果您观察到部分清除并找到了导致它的主要确定性方式,以便其他人也可能看到它,请大声广播! :)