简体   繁体   English

WPF DataGrid 内存泄漏

[英]WPF DataGrid memory leak

I have this code, and no matter what I do I keep getting a memory leak from the DataGrid data update.我有这个代码,无论我做什么,我都会从 DataGrid 数据更新中得到内存泄漏。 I've been looking at all the other answers to this problem here for days and I haven't found anything that works for me.几天来,我一直在这里查看有关此问题的所有其他答案,但没有找到任何对我有用的方法。 I have a WPF window and this code to update the data (it is a small version of what happens in the real code, but I get the same bug).我有一个 WPF 窗口和此代码来更新数据(它是实际代码中发生的事情的一个小版本,但我遇到了相同的错误)。

I have this WPF code:我有这个 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>

This class code:这个类代码:

/// <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"));
        });
    }
}

And this data class:这个数据类:

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 预览版中的问题。

I changed the timer period to 50 ms and run the program in debug for 80mn (~100 000 calls to ActualizacionUI_Tick ) the memory usage is stable and around 123mb.我将计时器周期更改为 50 毫秒,并在调试中运行程序 8000 万(对ActualizacionUI_Tick约 100 000 次调用),内存使用稳定,大约 123mb。

When you start the application there is indeed a period of time where the memory usage increase (and then it stabilize).当您启动应用程序时,确实有一段时间内存使用量增加(然后稳定)。 Using JetBrains dotMemory it appears that the surviving objects are related to ConditionalWeakTable implementation and retained by the MS.Internal.WeakEventTable which is cleaned-up once in awhile on the will of some internal heuristic.使用 JetBrains dotMemory,似乎幸存​​的对象与ConditionalWeakTable实现相关,并由MS.Internal.WeakEventTable保留, MS.Internal.WeakEventTable会根据某些内部启发式的意愿MS.Internal.WeakEventTable 清理

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM