我已经搜索过这个问题,但我只发现人们正在加载包含数百万条目的表格的问题。在我的情况下,情况并非如此。
我对 WPF 和实体框架都很陌生。我使用 Visual Studio 2010 数据源向导添加到数据库的连接。我使用拖放将视图从数据源拖放到我的 WPF 窗口中。该视图仅包含大约 32,000 条记录,选择大约需要 15 秒。
当我第一次构建并运行应用程序时,它运行良好并在窗口中显示数据。只是为了感受一下差异,我在 ListView 和 Datagrid 中显示相同的数据,但是当我只使用其中一个控件时没有什么不同:
当我第二次运行该应用程序时,它永远不会完成启动。它只显示“忙碌”光标,然后在一段时间后抛出 OutOfMemoryException。如果我在任务管理器中查看性能,内存只会不断上升,直到遇到异常。
我对此进行了调试:执行 EF 查询时不会发生这种情况。我什至让它将查询结果保存到一个列表中,并将其分配给窗口的数据源。我可以在调试器中看到查询终止并且列表生成良好,我可以在调试器中检查它。
这是查询运行后的数据绑定机制,似乎什么都没有泄漏内存然后抛出。顺便说一句,我没有可以发布的调用堆栈。
有没有其他人遇到过这个问题,你是如何解决的?
以下是更多信息:它是 Windows 7。
MainWindow.xaml 看起来像这样:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:my="clr-namespace:WpfApplication2">
<Window.Resources>
<CollectionViewSource x:Key="vMyViewSource" d:DesignSource="{d:DesignInstance my:VMyView, CreateList=True}" />
</Window.Resources>
<Grid DataContext="{StaticResource vMyViewSource}">
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="20"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Text="my view in a ListView:"/>
<ListView Grid.Row="1"
ItemsSource="{Binding}"
Margin="0"
Name="vMyListView"
SelectionMode="Single">
<ListView.ItemContainerStyle>
<Style>
<Setter Property="Control.HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Control.VerticalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn x:Name="IDColumn1" Header="ID" Width="80">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Margin="6,-1,-6,-1" Text="{Binding Path=ID,Mode=OneWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn x:Name="Name" Header="Name" Width="80">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Margin="-6,-1" Text="{Binding Path=Name, Mode=OneWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
... (more GridViewColumns)
</GridView>
</ListView.View>
</ListView>
<TextBlock Grid.Row="2" Text="my view in a DataGrid:"/>
<DataGrid Grid.Row="3"
AutoGenerateColumns="False"
EnableRowVirtualization="True"
HorizontalAlignment="Left"
ItemsSource="{Binding}"
Margin="0"
Name="vMyViewDataGrid"
RowDetailsVisibilityMode="VisibleWhenSelected"
VerticalAlignment="Top" >
<DataGrid.Columns>
<DataGridTextColumn x:Name="IDColumn" Binding="{Binding Path=ID}" Header="ID" Width="SizeToHeader" />
<DataGridTextColumn x:Name="NameColumn" Binding="{Binding Path=Name}" Header="Name" Width="SizeToHeader" />
... (more DataGridTextColumns, also some with a CellTemplate with a TextBox inside)
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
这是 MainWindow 的 Window_Loaded 方法(大部分代码是由数据源向导自动生成的):
private void Window_Loaded(object sender, RoutedEventArgs e)
{
WpfApplication2.MyEntities MyEntities = new WpfApplication2.MyEntities();
// Load data into VMyView. You can modify this code as needed.
System.Windows.Data.CollectionViewSource VMyViewViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("vMyViewViewSource")));
System.Data.Objects.ObjectQuery<WpfApplication2.VMyView> VMyViewQuery = this.GetVMyViewQuery(MyEntities);
var data = VMyViewQuery.Execute(System.Data.Objects.MergeOption.AppendOnly).ToList(); // I added the ToList() to make the query execute here
VMyViewViewSource.Source = data;
} // it gets here fine and loads the data
我不敢相信这里有什么不寻常的地方,发生了什么,我怎样才能摆脱这个问题?