简体   繁体   English

绑定WPF DataGrid ItemsSource会造成内存泄漏

[英]Binding WPF DataGrid ItemsSource creates memory leak

I'm simply creating a Observable collection in Background and binding to it. 我只是在背景中创建一个Observable集合并将其绑定。

All objects inherit from INotifyPropertyChanged. 所有对象都继承自INotifyPropertyChanged。 but nevertheless the Memory consumption is continuously raising. 但是尽管如此,内存消耗仍在不断增加。

The following Objects instances are continuously raising 以下Objects实例不断提高

WeakReference                                                                                       
FrugalObjectList<WeakEventManager+Listener>                                                         
ConditionalWeakTable<TKey, TValue>+Entry<Object, Object>[]                                        
WeakEventTable+EventKey                                                                             
ConditionalWeakTable<Object, Object>                                                              
SingleItemList<WeakEventManager+Listener>                                                           
Object                                                                                              
Int32[]                                                                                             
WeakEventManager+ListenerList<NotifyCollectionChangedEventArgs>                                     
WeakEventManager+ListenerList<PropertyChangedEventArgs>                                             
HybridDictionary                                                                                    
ListDictionary                                                                                      
ListDictionary+DictionaryNode                                                                       
WeakEventManager+ListenerList<EventArgs>                                                            
WeakEventManager+ListenerList<CurrentChangingEventArgs>                                             
CollectionRecord                                                                                    

I'm using .net 4.5.2. 我正在使用.net 4.5.2。

See also the following Screenshots: 另请参见以下屏幕截图:

MemoryConsumptionOverview MemoryConsumptionOverview

ClassesIncreasing ClassesIncreasing

Attached the sample code 随附示例代码

XAML Markup: XAML标记:

<Window x:Class="BindingDataGridTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="120" Width="200"
        DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
        <DataGrid ItemsSource="{Binding BindingVals, Mode=OneWay}" />
    </Grid>
</Window>

Code behind: 后面的代码:

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Threading;

namespace BindingDataGridTest
{
    public partial class MainWindow : INotifyPropertyChanged
    {

        public ObservableCollection<Values> BindingVals { get; set; }

        public MainWindow()
        {
            BindingVals = new ObservableCollection<Values>();
            InitializeComponent();

            DispatcherTimer myTimer = new DispatcherTimer { Interval = new TimeSpan(20) };
            myTimer.Tick += CreateVals;
            myTimer.Start();

        }
        private void CreateVals(object sender, EventArgs e)
        {
            Values myMainval = new Values
            {
                MyVal = "1V" + new Random().Next()
            };

            BindingVals.Clear();
            BindingVals.Add(myMainval);

            GC.Collect();
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

    public class Values : INotifyPropertyChanged
    {
        public string MyVal { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;

    }

}

It's caused by DispatcherTimer. 这是由DispatcherTimer引起的。

A DispatcherTimer will keep an object alive whenever the object's methods are bound to the timer. 每当对象的方法绑定到计时器时,DispatcherTimer都会使该对象保持活动状态。 https://msdn.microsoft.com/ru-ru/library/system.windows.threading.dispatchertimer(v=vs.110).aspx https://msdn.microsoft.com/ru-ru/library/system.windows.threading.dispatchertimer(v=vs.110).aspx

Use System.Timers.Timer instead and Dispatcher separately. 分别使用System.Timers.Timer和Dispatcher。

    public MainWindow()
    {
        BindingVals = new ObservableCollection<Values>();
        InitializeComponent();

        System.Timers.Timer myTimer = new Timer {Interval = 20};
        myTimer.Elapsed += CreateVals;
        myTimer.Start();

    }

    private void CreateVals(object sender, EventArgs e)
    {
        Dispatcher.Invoke(() =>
        {
            Values myMainval = new Values
            {
                MyVal = "1V" + new Random().Next()
            };

            BindingVals.Clear();
            BindingVals.Add(myMainval);

            GC.Collect();
        });

    }

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

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