【问题标题】:Is using global cache a bad idea for passig complex object on navigation? If it's, any alternative?在导航中使用全局缓存对于 passig 复杂对象是一个坏主意吗?如果是的话,有什么替代方案吗?
【发布时间】:2016-01-27 22:40:36
【问题描述】:

我一直在 UWP 应用程序中使用带有页面导航方法的参数传递没有问题(对象序列化和反序列化)。随着我的对象(作为参数传递)的大小增加,当应用程序暂停并且 SuspensionManager 尝试序列化导航参数并将其保存到本地存储时,我开始遇到问题。我得到一个异常,表明我认为大小限制为 8K(并假设我无法控制这个大小)。

所以我正在考虑通过内存缓存而不是导航参数传递参数(例如,将我的复杂数据对象保存到内存中以 nameof(PageNavigatedToType) 为键的字典中,并在目标页面中检索 NavigatedTo 上的缓存数据。我的担心可能会增加内存使用量,例如不确定将特定字典值设置为 null(不再需要时)是否会对全局内存(我的意思是应用程序范围)产生如此大的影响。

任何想法和建议表示赞赏。

【问题讨论】:

  • 我的 This answer 可能会对您有所帮助。
  • 感谢您的指点。我假设全局缓存不是一个好主意。您是否有一个参考链接(如果有)来解释第二个要点,即“或者在任何类型的 Manager 类中保留对它们的引用,它是...的成员”。谢谢。
  • 遗憾的是,没有任何参考。它最终进入全局缓存 - 或称为管理器 - 用于复杂数据。通过导航参数处理这些没有意义。但是,这个管理器应该或多或少像一个Stack:把一些东西放到导航(参数)堆栈上,下一页打开将采用该导航(参数)。
  • @Hedro 但是当应用程序暂停时问题就会出现。暂停时导航参数需要序列化并保存到本地存储,超过一定大小时会导致异常。这就是我的问题开始的地方。即使是复杂的对象,我也一直在使用导航参数而没有问题。

标签: c# caching windows-runtime uwp


【解决方案1】:

您不能使用LocalSettings 存储高于 8k 的值,并且每个复合设置的大小不能超过 64K 字节。

ApplicationData.LocalSettings | localSettings property

如果您在SuspensionManager 处理应用程序恢复时需要恢复大量数据,则最好将值保存为键,然后从另一个位置或过程恢复完整对象。正如你所建议的那样。

我正在考虑通过内存缓存而不是 导航参数(例如,将我的复杂数据对象保存到字典中 在内存中以 nameof(PageNavigatedToType) 为键并检索 在目标页面的 NavigatedTo 上缓存数据。

您的担忧

我担心内存使用量可能会增加,但不确定 如果将特定字典值设置为 null (如果没有 更需要)对全局内存有很大的影响(我的意思是 应用范围)。

这是一个合法的问题,但是您可以处理较短的对象范围,一旦 GC“检测到”内存需求,它将根据您的对象范围将对象释放到代码中。

如果您释放一个字典值 - 将其设置为 null- 可能足以在“如果和何时”不存在对此类对象的更多引用时被回收。

短对象范围可以通过多种方式实现,因为这是一个概念。

  • 仅声明局部方法变量而不是类变量/属性就是其中之一。
  • 当您使用IDisposable 对象时。 using 关键字确保正确使用IDisposable 对象并允许它们为garbagecollect
using (Font font1 = new Font("Arial", 10.0f)) 
{
    byte charset = font1.GdiCharSet;
}
  • C# 允许您通过方括号将字段范围控制到方法中,这是一个语法帮助程序,用于控制您的字段将在哪个范围内使用,因此您可以选择在关闭方括号后释放这些资源。如果您的字段不是 IDisposable 字段,您当然可以使用它。
public void MyMethod()
{
    ...
    ...
    {
        var o = new MyObject();
        var otherReferenceToSameObject = o;
        var s = "my string";
        ...
        ...
        ...
        ...

        otherReferenceToSameObject = o = null;
        s = null;
    }
    ...
    ...
}
  • 请记住,GC 是由其自己的算法确定的,我们对此没有足够的控制权,但对我们的资源进行一些控制可以帮助GC 做得更好。

【讨论】:

  • 感谢您的回复。您能否解释一下以下内容:“但是您可以处理短的对象范围” 如何?您还说“将其设置为空” - 这是一个错字还是您的意思是将其设置为空。如果有一种方法可以将我的全局对象标记为具有较短的范围,以便 GC 可以更快地采取行动——我不知道并且想知道。
  • 我已经为答案添加了一些补充信息。
  • 我可以理解范围界定——毫无疑问。我的问题是一旦一个对象是全局的,除了将它设置为 null 并希望 GC 将回收内存之外没有太多控制。这是我的困境,想知道是否有更聪明的方法来处理在 App 范围内定义的全局对象。导航参数序列化和反序列化非常好,但正如您所指出的,当应用程序暂停时会严重失败,因为 NavigationService 尝试保存到具有内存大小限制的本地存储。
  • 对在 App 范围内定义的全局对象唯一能做的就是确保在不再需要时将它们设置为 null。此外,经过验证的子对象可能对 GC 有用。
  • 谢谢,有道理。在处理全局对象时,我可以理解子对象,但是您使用的短语 verified child objects 引起了我的注意。想评论 已验证的子对象 吗?谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-29
  • 2012-10-15
  • 1970-01-01
  • 2014-08-23
  • 1970-01-01
  • 2014-07-16
  • 1970-01-01
相关资源
最近更新 更多