如何处理内存
How to handle memory
在使用 UWP 进行探索时,我尝试使用这个简单的应用程序时遇到了问题。
我的应用程序在 Windows Phone 和 512mb ram 中自动关闭,因为内容太多,我想这会使 phone 运行 内存不足.
我想问一下在不导致应用程序崩溃的情况下加载内容的正确方法是什么?
我应该在屏幕末尾实现更多加载并加载一些内容并在单击时隐藏另一个内容还是有其他更好的解决方案?
我读过一些关于 UI 虚拟化的内容,但我不知道在这种情况下如何实施它。将提供一个示例。
<ScrollViewer HorizontalScrollBarVisibility="Hidden" Height="500" Loaded="Populate">
<StackPanel x:Name="ContentsPanel"></StackPanel>
</ScrollViewer>
void Populate(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 1000; i++)
{
ContentsPanel.Children.Add(new TextBlock
{
Text = @"ipsumSed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium,
totam rem aperiam,
eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit,
sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.Neque porro quisquam est,
qui dolorem ipsum quia dolor sit amet,
consectetur,
adipisci velit,
sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.Ut enim ad minima veniam,
quis nostrum exercitationem ullam corporis suscipit laboriosam,
nisi ut aliquid ex ea commodi consequatur ? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur,
vel illum qui dolorem eum fugiat quo voluptas nulla pariatur ?
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
});
}
}
到达滚动查看器的末尾后,您可以加载更多内容。 How to find that ScrollViewer is scrolled to the end in WPF? 提供了示例。
大多数时候你 运行 内存不足是因为你加载了大图像,或者你没有 using/have 破坏虚拟化。这是一个过于简单的规则,但您不应该将堆栈面板放在滚动查看器中。如果你发现自己想要这样做,你可能想要的实际上是一个绑定到某种 ItemsSource 的 ListView(ObservableCollection<T>
如果你想稍后能够 add/remove 事情,或者任何 IEnumerable<T>
如果它是完全静态的。如果列表视图的内容是同类的,您可以使用 ListView.ItemTemplate,如果内容是异构的,您可以使用 ListView.ItemTemplateSelector 为不同种类的项目选择不同的模板。
当您使用 ListView 时,XAML 运行时间只会为屏幕上当前显示的内容创建足够的 UI 控件 + 顶部和底部的一点点确保滚动流畅。请注意,这是 UI 虚拟化,而不是内容虚拟化,因为您可以在绑定为 ItemSource 的 class 上实施 ISupportIncrementalLoading。
编辑以添加请求的示例:
<ListView x:Name="contentsList" HorizontalScrollBarVisibility="Hidden" Height="500" Loaded="Populate">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" /> <!-- this is not actually needed in this example because its actually the default data template for a list view but ive included it for completeness -->
</DataTemplate>
</ListView.ItemTemplate>
<ListView>
void Populate(object sender, RoutedEventArgs e)
{
var madeList = new List<string>()
for(int i = 0; i < 1000; i++)
{
madeList.Add(@"ipsumSed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium,
totam rem aperiam,
eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit,
sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.Neque porro quisquam est,
qui dolorem ipsum quia dolor sit amet,
consectetur,
adipisci velit,
sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.Ut enim ad minima veniam,
quis nostrum exercitationem ullam corporis suscipit laboriosam,
nisi ut aliquid ex ea commodi consequatur ? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur,
vel illum qui dolorem eum fugiat quo voluptas nulla pariatur ?
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.");
}
contentsList.ItemsSource = madeList;
}
在使用 UWP 进行探索时,我尝试使用这个简单的应用程序时遇到了问题。 我的应用程序在 Windows Phone 和 512mb ram 中自动关闭,因为内容太多,我想这会使 phone 运行 内存不足.
我想问一下在不导致应用程序崩溃的情况下加载内容的正确方法是什么? 我应该在屏幕末尾实现更多加载并加载一些内容并在单击时隐藏另一个内容还是有其他更好的解决方案?
我读过一些关于 UI 虚拟化的内容,但我不知道在这种情况下如何实施它。将提供一个示例。
<ScrollViewer HorizontalScrollBarVisibility="Hidden" Height="500" Loaded="Populate">
<StackPanel x:Name="ContentsPanel"></StackPanel>
</ScrollViewer>
void Populate(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 1000; i++)
{
ContentsPanel.Children.Add(new TextBlock
{
Text = @"ipsumSed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium,
totam rem aperiam,
eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit,
sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.Neque porro quisquam est,
qui dolorem ipsum quia dolor sit amet,
consectetur,
adipisci velit,
sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.Ut enim ad minima veniam,
quis nostrum exercitationem ullam corporis suscipit laboriosam,
nisi ut aliquid ex ea commodi consequatur ? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur,
vel illum qui dolorem eum fugiat quo voluptas nulla pariatur ?
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
});
}
}
到达滚动查看器的末尾后,您可以加载更多内容。 How to find that ScrollViewer is scrolled to the end in WPF? 提供了示例。
大多数时候你 运行 内存不足是因为你加载了大图像,或者你没有 using/have 破坏虚拟化。这是一个过于简单的规则,但您不应该将堆栈面板放在滚动查看器中。如果你发现自己想要这样做,你可能想要的实际上是一个绑定到某种 ItemsSource 的 ListView(ObservableCollection<T>
如果你想稍后能够 add/remove 事情,或者任何 IEnumerable<T>
如果它是完全静态的。如果列表视图的内容是同类的,您可以使用 ListView.ItemTemplate,如果内容是异构的,您可以使用 ListView.ItemTemplateSelector 为不同种类的项目选择不同的模板。
当您使用 ListView 时,XAML 运行时间只会为屏幕上当前显示的内容创建足够的 UI 控件 + 顶部和底部的一点点确保滚动流畅。请注意,这是 UI 虚拟化,而不是内容虚拟化,因为您可以在绑定为 ItemSource 的 class 上实施 ISupportIncrementalLoading。
编辑以添加请求的示例:
<ListView x:Name="contentsList" HorizontalScrollBarVisibility="Hidden" Height="500" Loaded="Populate">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" /> <!-- this is not actually needed in this example because its actually the default data template for a list view but ive included it for completeness -->
</DataTemplate>
</ListView.ItemTemplate>
<ListView>
void Populate(object sender, RoutedEventArgs e)
{
var madeList = new List<string>()
for(int i = 0; i < 1000; i++)
{
madeList.Add(@"ipsumSed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium,
totam rem aperiam,
eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit,
sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.Neque porro quisquam est,
qui dolorem ipsum quia dolor sit amet,
consectetur,
adipisci velit,
sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.Ut enim ad minima veniam,
quis nostrum exercitationem ullam corporis suscipit laboriosam,
nisi ut aliquid ex ea commodi consequatur ? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur,
vel illum qui dolorem eum fugiat quo voluptas nulla pariatur ?
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.");
}
contentsList.ItemsSource = madeList;
}