WPF 数据网格内存泄漏



我有这段代码,无论我做什么,我都会从DataGrid数据更新中得到内存泄漏。几天来,我一直在研究这个问题的所有其他答案,但我还没有找到任何适合我的东西。我有一个 WPF 窗口和这段代码来更新数据(它是真实代码中发生的事情的一个小版本,但我得到了同样的错误)。

我有这个 WPF 代码:

<Window x:Class="TremendoMemoryLeak.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TremendoMemoryLeak"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="450" Width="800">
<Grid>
<DataGrid ItemsSource="{Binding Hmis, Mode=OneWay}" AutoGenerateColumns="False" IsReadOnly="True">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Estado">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Ellipse Fill="{Binding Estado}" HorizontalAlignment="Left" Height="25" Stroke="Black" VerticalAlignment="Top" Width="25"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Dato1" Binding="{Binding Dato1}"/>
<DataGridTextColumn Header="Dato2" Binding="{Binding Dato2}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>

此类代码:

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
public ObservableCollection<Datos> Hmis { get; } = new ObservableCollection<Datos>();
private System.Threading.Timer timer;
public MainWindow()
{
InitializeComponent();
timer = new System.Threading.Timer(ActualizacionUI_Tick, null, 1000, 1000);
}
public event PropertyChangedEventHandler? PropertyChanged;
private void ActualizacionUI_Tick(object data)
{
Datos dato1 = new Datos() { Dato1 = "1", Dato2 = "2" };
Datos dato2 = new Datos() { Dato1 = "1", Dato2 = "2" };
Datos dato3 = new Datos() { Dato1 = "1", Dato2 = "2" };
Dispatcher.Invoke(() =>
{
dato1.Estado = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF5DC75D"));
dato2.Estado = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF5DC75D"));
dato3.Estado = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF5DC75D"));
Hmis.Clear();
Hmis.Add(dato1);
Hmis.Add(dato2);
Hmis.Add(dato3);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Hmis"));
});
}
}

而这个数据类:

public class Datos : INotifyPropertyChanged
{
public Brush Estado { get; set; }
public string Dato1 { get; set; }
public string Dato2 { get; set; }
public event PropertyChangedEventHandler? PropertyChanged;
}

我正在 Visual Studio 2022 上执行该解决方案,在 VS2019 上对其进行测试时,内存泄漏突然消失了,因此这似乎是 2022 年预览版中的一个问题。

我将计时器周期更改为 50 毫秒,并在调试中运行程序 80mn(~100 000 次调用ActualizacionUI_Tick),内存使用量稳定,约为 123MB。

当您启动应用程序时,确实有一段时间内存使用量增加(然后稳定下来)。使用 JetBrains dotMemory,似乎幸存的对象与ConditionalWeakTable实现有关,并由MS.Internal.WeakEventTable保留,根据一些内部启发式的意愿偶尔清理。