我如何取消注册“匿名”事件处理程序

说如果我听一个事件:

Subject.NewEvent += delegate(object sender, NewEventArgs e) { //some code }); 

现在我该如何取消注册这个事件? 或者只是让内存泄漏?

如果你需要注销一个事件,我build议避免匿名代理的事件处理程序。

在这种情况下,将其分配给本地方法会更好 – 您可以干净地取消订阅活动。

给你的匿名委托实例一个名字:

 EventHandler<NewEventArg> handler = delegate(object sender, NewEventArgs e) { //some code }; Subject.NewEvent += handler; Subject.NewEvent -= handler; 

要在第一次调用时删除处理程序:

 //SubjectType Subject = ..... already defined if using (2) EventHandler handler = null; handler = delegate(object sender, EventArgs e) { // (1) (sender as SubjectType).NewEvent -= handler; // or // (2) Subject.NewEvent -= handler; // do stuff here }; Subject.NewEvent += handler; 

您可以创build从所有事件侦听器注销的方法。 这不完全是你想要的,但有时它可以是有帮助的。 例如(这真的有效=)):

  class Program { static void Main(string[] args) { A someClass = new A(); someClass.SomeEvent += delegate(object sender, EventArgs e) { throw new NotImplementedException(); }; someClass.ClearEventHandlers(); someClass.FireEvent(); Console.WriteLine("No error."); } public class A { public event EventHandler SomeEvent; public void ClearEventHandlers() { Delegate[] delegates = SomeEvent.GetInvocationList(); foreach (Delegate delegate in delegates) { SomeEvent -= (EventHandler) delegate; } } public void FireEvent() { if (SomeEvent != null) { SomeEvent(null, null); } } } } 

你需要一个你的匿名函数的名字,然后,只有这个名字在范围内,你才可以这样做:

  var handler = new EventHandler(delegate(object o, EventArgs e) { //do something... }; Subject.NewEvent += handler; // later on while handler is still in scope... Subject.NewEvent -= handler; 

除了泄漏之外,您是否需要取消注册?

关于“或者只是让内存泄漏”一点,当垃圾收集器清理主体时,你的匿名代理也应该清理干净,所以不应该有泄漏。

还有另外一个(我的)问题涉及到一些(太多)细节: 与lambda一起使用的弱事件处理模型 。

但是,现在Reactive Framework已经出来,我认真考虑在这种情况下进行研究。