删除UWP中的导航缓存

时间:2018-06-23 17:26:12

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

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

1 个答案:

答案 0 :(得分:1)

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

但是有解决方案:

  1. 请勿在XAML代码中使用NavigationCacheMode
  2. 在每个页面上都必须覆盖OnNavigatedTo(),并且当NavigationMode新建时,更改NavigationCacheMode是必需的
  3. 在每个页面上必须覆盖OnNavigatingFrom(),并且当NavigationMode后退时,更改为NavigationCacheMode禁用

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

但是当用户向前按下页面时,页面会被重新分配,因此先前的状态会丢失。

在某些情况下,“禁用缓存”模式不够用,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派生。