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