一次性删除所有事件处理程序

Dav*_*ten 5 vb.net events

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

文档有时可以交换对象,但是单个对象永远不应该是多个文档的"一部分".

我的文档类包含许多用作事件处理程序的方法.每当一个对象进入文档时,我就会AddHandler用来设置事件,每当从文档中删除一个对象时,我就会RemoveHandler用来撤消损坏.但是,有些情况下很难确保所有步骤都得到适当的处理,因此我最终可能会遇到流氓事件处理程序.

长话短说; 如何删除指向特定方法的所有处理程序?注意,我没有可能的事件源列表,这些可以存储在任何地方.

就像是:

RemoveHandler *.SolutionExpired, AddressOf DefObj_SolutionExpired
Run Code Online (Sandbox Code Playgroud)

Ben*_*esh 5

你可以用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);
}
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);
}
Run Code Online (Sandbox Code Playgroud)

您应该注意,它不会改变您传递给它的代理的内容,它会返回一个更改的委托.因此,您无法在表单上删除表单上的按钮上更改事件,button1.Click只能在表单上使用+=-=使用,而不是=.这不会编译:

button1.Click = Delegate.RemoveAll(d, d) as EventHandler;
Run Code Online (Sandbox Code Playgroud)

此外,请确保无论您在何处实施此项目,都要注意竞争条件的潜力.如果你要从另一个线程调用的事件中删除处理程序,你可能会遇到一些非常奇怪的行为!

  • 考虑到OP需要从他没有私有级别访问权限的事件中删除处理程序,我不知道这是可以接受的.我肯定错过了什么! (5认同)
  • 这也是C#而OP的问题是关于vb.net.虽然两者有很多重叠,但事件语法是一个很大的不同之处 (4认同)