C# EventHandler内存泄漏

C# EventHandler内存泄漏,c#,events,C#,Events,我有一个ObservaleCollection,它保存项,每个项都包含事件MessageEvent,订阅一些匿名方法。主要问题是为什么在Items.Clear()之后匿名还活着吗 Xaml: 代码: 命名空间WpfApplication207 { /// ///MainWindow.xaml的交互逻辑 /// 公共部分类主窗口:窗口 { 数据D=新数据(); 公共主窗口() { 初始化组件(); DataContext=D; } 私有无效按钮\u单击(对象发送者,路由目标e) { D.清

我有一个ObservaleCollection,它保存项,每个项都包含事件MessageEvent,订阅一些匿名方法。主要问题是为什么在
Items.Clear()之后匿名还活着吗

Xaml:


代码:

命名空间WpfApplication207
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
数据D=新数据();
公共主窗口()
{
初始化组件();
DataContext=D;
}
私有无效按钮\u单击(对象发送者,路由目标e)
{
D.清洁收集();
}
}
公共类项目
{
公共int id{get;set;}
公共委托无效发送消息(int i);
公共事件发送消息事件;
公共项目()
{
MessageEvent+=(o)=>{Console.WriteLine(“坏事发生”);};
updateSync();
}
public void updateSync()
{
动作测试=新动作(DoSomeWork);
IAsyncResult结果=Test.BeginInvoke(null,null);
}
公共工程
{
while(true)
{
系统线程线程睡眠(3000);
if(MessageEvent!=null)
{
消息事件(1);
}
}
}
}
公共类数据
{
公共ObservableCollection项{get;set;}
公共数据()
{
Items=新的ObservableCollection();
添加(新项目{id=1});
}
公共收集()
{
Items.Clear();
}
}
主要问题是为什么在
Items.Clear();
anonymous之后仍然存在

因为使用
items.Clear()
并不意味着项目被垃圾收集。它只意味着
ObservableCollection
不再包含对这些项目的引用,如果他是唯一这样做的人,那么只有在下一个GC中才会收集这些项目,其中下一个GC时间是由运行时确定的任意时间

如果希望项目停止打印这些消息,可以执行两项操作:

  • 将代理作为一个字段放入
    类中
  • 一旦项目不再需要使用,使用一次性模式取消注册:

    public class Item : IDisposable
    {
        public int id { get; set; }
    
        private Action action;
        public event SendMessage MessageEvent;
    
        public Item()
        {
            action = () => Console.WriteLine("Bad thing happens");
            MessageEvent += action;
            UpdateAsync();
        }
    
        public void Dispose()
        {
            Dispose(true);
        }
    
        protected virtual void Dispose(bool disposing)
        {
            if (!disposing)
                return;
    
            MessageEvent -= action;
        }
    }
    
    public class Data
    {
        public ObservableCollection<Item> Items { get; set; }
        public Data()
        {
            Items = new ObservableCollection<Item>();
            Items.Add(new Item { id = 1});
        }
    
        public void CleanCollection()
        {
            foreach (var item in Items)
            {
                item.Dispose();
            }
    
            items.Clear();
        }
    }
    
    公共类项目:IDisposable
    {
    公共int id{get;set;}
    私人行动;
    公共事件发送消息事件;
    公共项目()
    {
    action=()=>Console.WriteLine(“坏事发生”);
    MessageEvent+=操作;
    updateSync();
    }
    公共空间处置()
    {
    处置(真实);
    }
    受保护的虚拟void Dispose(bool disposing)
    {
    如果(!处理)
    返回;
    MessageEvent-=操作;
    }
    }
    公共类数据
    {
    公共ObservableCollection项{get;set;}
    公共数据()
    {
    Items=新的ObservableCollection();
    添加(新项目{id=1});
    }
    公共收集()
    {
    foreach(项目中的var项目)
    {
    item.Dispose();
    }
    items.Clear();
    }
    }
    
  • 但是当我在Items.Clear()之后调用GC.Collect()时,什么都没有发生,它仍然是活动的。
    namespace WpfApplication207
    {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Data D = new Data();
        public MainWindow()
        {
            InitializeComponent();
            DataContext = D;
    
        }
    
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            D.CleanCollection();
        }
    }
    
    public class Item
    {
        public int id { get; set; }
    
        public delegate void SendMessage (int i);
    
        public event SendMessage MessageEvent;
    
        public Item()
        {
            MessageEvent += (o) => { Console.WriteLine("Bad thing happens"); };
            UpdateAsync();
        }
    
        public void UpdateAsync()
        {
            Action Test = new Action(DoSomeWork);
            IAsyncResult result = Test.BeginInvoke(null,null);
        }
    
        public void DoSomeWork()
        {
            while(true)
            {
                System.Threading.Thread.Sleep(3000);
                if (MessageEvent!=null)
                {
                    MessageEvent(1);
                }
            }
        }
    }
    public class Data
    {
        public ObservableCollection<Item> Items { get; set; }
        public Data()
        {
            Items = new ObservableCollection<Item>();
            Items.Add(new Item { id = 1});
        }
    
        public void CleanCollection()
        {
            Items.Clear();
        }
    }
    
    public class Item : IDisposable
    {
        public int id { get; set; }
    
        private Action action;
        public event SendMessage MessageEvent;
    
        public Item()
        {
            action = () => Console.WriteLine("Bad thing happens");
            MessageEvent += action;
            UpdateAsync();
        }
    
        public void Dispose()
        {
            Dispose(true);
        }
    
        protected virtual void Dispose(bool disposing)
        {
            if (!disposing)
                return;
    
            MessageEvent -= action;
        }
    }
    
    public class Data
    {
        public ObservableCollection<Item> Items { get; set; }
        public Data()
        {
            Items = new ObservableCollection<Item>();
            Items.Add(new Item { id = 1});
        }
    
        public void CleanCollection()
        {
            foreach (var item in Items)
            {
                item.Dispose();
            }
    
            items.Clear();
        }
    }