开发者

wp7 - TextBlock with a lot of text - huge memory usage - how to avoid it?

I have a problem in my app and I don't know if i开发者_JS百科t is normal or not. I have a textblock in my application that needs to display a large amount of text (2000-4000 chars). Anyway there is a limit of 2048 pixels I think so my text is cropped, this is no problem, I use this : http://blogs.msdn.com/b/priozersk/archive/2010/09/08/creating-scrollable-textblock-for-wp7.aspx .

The problem is that the longer the text the more memory it consumes. Without the very long text hack from the link above, the textblock consumes around 10mb of memory! If I use the ScrollableTextBlock from the link above, the amount of memory is going even further and can reach up to 30-40 mb.. There is no limit. So it seems that the memory usage is related with the area that is drawn...

Is there a way to reduce memory usage for long texts? Has BitmapCach anything to do with this problem and can I disable it? You can easily reproduce this problem by just adding a textblock with a very long text and you can check memory usage with this code, you will see that with just 1 textblock with long text, the peak memory goes up by 10mb or more:

        long deviceTotalMemory = (long)DeviceExtendedProperties.GetValue("DeviceTotalMemory");
        long applicationCurrentMemoryUsage = (long)DeviceExtendedProperties.GetValue("ApplicationCurrentMemoryUsage");
        long applicationPeakMemoryUsage = (long)DeviceExtendedProperties.GetValue("ApplicationPeakMemoryUsage");

        Debug.WriteLine("### deviceTotalMemory             : " + deviceTotalMemory);
        Debug.WriteLine("### applicationCurrentMemoryUsage : " + applicationCurrentMemoryUsage);
        Debug.WriteLine("### applicationPeakMemoryUsage    : " + applicationPeakMemoryUsage);


I came across similar issues when creating Overflow7

The problems I encountered were to do with the fact that if you use a StackPanel inside a ScrollViewer, then the ScrollViewer insists that all of the StackPanel is rendered, not just the visible portion.

I read around and there were 2 general solutions:

  • use UI virtualization techniques - e.g. VirtualizingStackPanel
  • use data virtualization techniques - e.g. crafting your own paging

To get round this in Overflow7 I made use of ListBoxes instead of the ScrollViewer/StackPanel combo. The internals part of ListBox use a VirtualizingStackPanel - and this VirtualizingStackPanel renders just whats on the screen, not the entire scrollable client area.

This was a bit "hacky" but worked well. If you have time, then I believe a better solution would be to improve the ScrollableTextBlock implementation so that it uses VirtualizingStackPanel - there are good posts about how to use this on (for example) WPF VirtualizingStackPanel for increased performance


For a large amount of text in a single control it is normal to consume larger amounts of memory than expected. As it was mentioned before, you can page the text or implement dynamic loading, where only chucks of text are loaded for the visible area. That way you won't be keeping a large string in memory.

In your case, caching would be related to re-use and content reloads whenever the user switches to a different page, not to the initial content loading and manipulation process.


I know this is an old question, however I wanted to add one more solution.

http://blogs.msdn.com/b/stankovski/archive/2013/08/27/yet-another-scrollable-textblock-for-windows-phone.aspx

To accomplish my task I have encapsulated the "splitting" logic into a separate class that produces the output as a List of strings. You can then bind that list to your favorite ListBox control and voila, you have a ginormous text block. The splitting logic has been optimized for performance so you'll get a much better processing time then ScrollableTextBlock by Alex. Also, since you can bind the list to any ListBox control that supports virtualization you will have a much more conservative memory footprint.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜