一次删除所有事件处理程序 [英] Removing all event handlers in one go

查看:126
本文介绍了一次删除所有事件处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:我有一个包含对象列表的文档类。这些对象引发了诸如SolutionExpired,DisplayExpired等事件。文档需要对此做出回应。



文档有时可以交换对象,但单个对象不应该是部分的一个以上的文档。



我的文档类包含一些用作事件处理程序的方法。每当对象进入文档时,我使用AddHandler设置事件,每当从文档中删除对象时,我使用RemoveHandler来消除损坏。然而,有些情况下,很难确保所有步骤都能正确使用,因此我可能会因流氓事件处理程序而结束。



长篇小说;如何删除指向特定方法的所有处理程序?请注意,我没有潜在的事件来源列表,可以存储在任何地方。



如下所示:



RemoveHandler * .SolutionExpired,AddressOf DefObj_SolutionExpired

解决方案

可以使用Delegate.RemoveAll()。 (你感兴趣的部分是button2_Click)

  public void Form_Load(object sender,EventArgs e)
{
button1.Click + = new EventHandler(button1_Click);
button1.Click + = new EventHandler(button1_Click);
button2.Click + = new EventHandler(button2_Click);
TestEvent + = new EventHandler(Form_TestEvent);
}
事件EventHandler TestEvent;
void OnTestEvent(EventArgs e)
{
if(TestEvent!= null)
TestEvent(this,e);
}
void Form_TestEvent(object sender,EventArgs e)
{
MessageBox.Show(TestEvent fired);
}
void button2_Click(object sender,EventArgs e)
{
委托d = TestEvent为Delegate;
TestEvent = Delegate.RemoveAll(d,d)作为EventHandler;
}
void button1_Click(object sender,EventArgs e)
{
OnTestEvent(EventArgs.Empty);
}

你应该注意到,它不会改变你通过的代表的内容在它,它返回一个改变的代表。因此,您将无法更改从表单中删除的按钮上的事件,因为button1.Click只能使用+ =或 - =,而不是=。这不会编译:

  button1.Click = Delegate.RemoveAll(d,d)作为EventHandler; 

此外,请确保您正在实施的任何地方,竞争条件的潜力。如果您正在从另一个线程调用的事件中删除处理程序,您可能会遇到一些非常奇怪的行为!


Problem: I have a document class which contains a list of objects. These objects raise events such as SolutionExpired, DisplayExpired etc. The document needs to respond to this.

Documents can sometimes exchange objects, but a single object should never be 'part' of more than one document.

My document class contains a bunch of methods which serve as event handlers. Whenever an object enters the document, I use AddHandler to set up the events, and whenever an object is removed from the document I use RemoveHandler to undo the damage. However, there are cases where it's difficult to make sure all the steps are properly taken and I might thus end up with rogue event handlers.

Long story short; how do I remove all the handlers that are pointing to a specific method? Note, I don't have a list of potential event sources, these could be stored anywhere.

Something like:

RemoveHandler *.SolutionExpired, AddressOf DefObj_SolutionExpired

解决方案

You can use Delegate.RemoveAll(). (The part you're interested in is in button2_Click)

public void Form_Load(object sender, EventArgs e) 
{ 
  button1.Click += new EventHandler(button1_Click);
  button1.Click += new EventHandler(button1_Click);
  button2.Click += new EventHandler(button2_Click);
  TestEvent += new EventHandler(Form_TestEvent);
}
event EventHandler TestEvent;
void OnTestEvent(EventArgs e)
{
  if (TestEvent != null)
     TestEvent(this, e);
}
void Form_TestEvent(object sender, EventArgs e)
{
  MessageBox.Show("TestEvent fired");
}
void button2_Click(object sender, EventArgs e)
{
  Delegate d = TestEvent as Delegate;
  TestEvent = Delegate.RemoveAll(d, d) as EventHandler;
}
void button1_Click(object sender, EventArgs e)
{
  OnTestEvent(EventArgs.Empty);
}

You should note that it doesn't alter the contents of the delegates you pass in to it, it returns an altered delegate. Consequently, you won't be able to alter the events on a button you've dropped on a form from the form, as button1.Click can only have += or -= used on it, not =. This won't compile:

button1.Click = Delegate.RemoveAll(d, d) as EventHandler;

Also, be sure that wherever you're implementing this you're watching out for the potential of race conditions. You could end up with some really strange behavior if you're removing handlers from an event that is being called by another thread!

这篇关于一次删除所有事件处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆