vb.net - 一次性删除所有事件处理程序

标签 vb.net events

问题:我有一个包含对象列表的文档类。这些对象引发 SolutionExpiredDisplayExpired 等事件。文档需要对此做出响应。

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

我的文档类包含一堆用作事件处理程序的方法。每当一个对象进入文档时,我都会使用 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);
}
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);
}

您应该注意,它不会更改您传递给它的委托(delegate)的内容,它会返回更改后的委托(delegate)。因此,您将无法更改从表单拖放到表单上的按钮上的事件,因为 button1.Click 只能有 += 或其上使用的是 -=,而不是 =。这不会编译:

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

此外,请确保无论您在何处实现此操作,都要留意潜在的竞争条件。如果您从另一个线程调用的事件中删除处理程序,您最终可能会出现一些非常奇怪的行为!

关于vb.net - 一次性删除所有事件处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1150250/

相关文章:

asp.net - 为什么我会收到基于 Div 颜色样式的 SQL 错误消息?

c# - VB.NET 和 sizeof

events - F# Event.Filter 的性能成本/增益

javascript - Phaser - 不允许多个按键事件

c++ - 由于使用事件而产生的开销

sql - 使用多个过滤器过滤 sql 数据 vb.net (winform)

vb.net - 我的列表(字符串)被保存为 system.string (空)

vb.net - 取消引用字段时是否需要内存屏障(.net x86 或 x64)?

javascript - 使用 Sinon Js 测试事件触发后调用的回调

events - 如何在 Meteor 中处理自定义 jQuery 事件?