【问题标题】:Delete navigation cache in UWP删除 UWP 中的导航缓存
【发布时间】:2018-12-02 20:23:12
【问题描述】:

在我的 UWP 应用程序中,我不断地从第 1 页导航到第 2 页,再从第 2 页导航到第 1 页,并且此导航循环在两个页面中的提交按钮上再次重复。在应用程序启动时,它的性能很好,但是当页面导航得更远时,它会占用更多内存,并且在导航 15 或 20 次后应用程序变慢。我尝试通过减小导航缓存的大小来删除导航缓存,但它没有帮助,在我的研究中我发现如果导航模式设置为启用它会减少一些内存使用量。但是当我保持它启用时,以前的数据并没有消失。我需要一个解决方案来删除以前页面的内存,并使我的应用程序即使在多次导航后也能使用更少的内存。

【问题讨论】:

  • 是的,我读过。但问题是,如果我将 NavigationMode 保持启用状态,页面中的先前数据将不会出现。如果我根据第 1 页中的用户输入进行一些修改,然后当我从第 2 页返回时,这些修改不会进行。但是我每次回来都想要一个新的页面。
  • 请出示您的性能分析器。如果您执行强制 GC 收集,也会显示结果。

标签: c# performance memory-leaks uwp uwp-xaml


【解决方案1】:

问题是 UWP 引擎不会破坏您的页面,即使它不再位于导航堆栈中。

但是有解决办法:

  1. 不要在 XAML 代码中使用 NavigationCacheMode
  2. 在每个页面上都必须覆盖OnNavigatedTo(),并且当NavigationMode时,更改NavigationCacheMode 必需
  3. 在每个页面上都必须覆盖OnNavigatingFrom(),当NavigationMode 返回时,更改NavigationCacheMode Disabled

通过这种机制,您可以实现以下目标:导航堆栈上的每个页面都是 Cache=Required 并且不在导航堆栈上的每个页面都 Cache=Disabled。

但是有些当用户按下前进时,页面是新分配的,所以之前的状态会丢失。

在某些情况下,Disabled Cache 模式不够用,UWP 仍将页面保留在内存中。在这种情况下,我们必须删除缓存。如果我们将当前帧缓存大小重置为零并恢复为原始大小,我们就可以做到这一点。

这是我在每个页面中的代码:

    protected override void OnNavigatedTo( NavigationEventArgs navigationEvent )
    {
        // call the original OnNavigatedTo
        base.OnNavigatedTo( navigationEvent );

        // when the dialog displays then we create viewmodel and set the cache mode
        if( CreatedViewModel == null || navigationEvent.NavigationMode == NavigationMode.New )
        {
            // set the cache mode
            NavigationCacheMode = NavigationCacheMode.Required;

            // create viewmodel
            CreatedViewModel = CreateViewModel( navigationEvent.Parameter );
            DataContext = CreatedViewModel;
            CreatedViewModel.InitializeAsync().ConfigureAwait( false );
        }
    }

    protected override void OnNavigatingFrom( NavigatingCancelEventArgs navigationEvent )
    {
        // call the original OnNavigatingFrom
        base.OnNavigatingFrom( navigationEvent );

        // when the dialog is removed from navigation stack 
        if( navigationEvent.NavigationMode == NavigationMode.Back )
        {
            // set the cache mode
            NavigationCacheMode = NavigationCacheMode.Disabled;

            ResetPageCache();
        }
    }

    private void ResetPageCache()
    {
        int cacheSize = ((Frame)Parent).CacheSize;

        ((Frame)Parent).CacheSize = 0;
        ((Frame)Parent).CacheSize = cacheSize;
    }

一些注意事项:当您创建一个 BasePage 并将此代码放入其中时会更舒服,并且您可以从每个 Page 中的此 BasePage 派生。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-10
    • 2015-11-01
    • 1970-01-01
    • 2023-03-20
    • 2018-10-14
    • 1970-01-01
    相关资源
    最近更新 更多