如何在.NET中分配事件

时间:2010-06-03 19:33:08

标签: .net events

我刚刚意识到我并不完全理解为什么在.NET中使用+ =符号分配事件。

昨天当我需要移除一个事件而不考虑我正在做

时,我想到了这一点
someobject.onsomeevent += null

认为这会删除我之前分配的事件。

经过一番调查,我发现我必须

someobject.onsomeevent -= someeventmethod;

在搞清楚之后,我意识到我不明白如何在.NET中分配事件方法。

所以我有几个问题:

首先,这是否意味着我可以做到

someobject.onsomeevent += someeventmethod;
someobject.onsomeevent += someeventothermethod;

如果是这样,当 onsomeevent 发生时,它们都会被命中,并按照指定的顺序或同时进行?

此外,如何确定已将哪些事件方法分配给 someobject.onsomeevent

第二,有没有办法在某些类中保存事件方法,从someobject.onsomeevent中删除它们,并在通常触发事件的其他一些程序完成后重新分配它们?

5 个答案:

答案 0 :(得分:4)

关于您的第一个问题:默认情况下您会获得多播行为。也就是说,如果你有多个处理程序,那么默认情况下将按顺序调用事件处理程序(除非其中一个抛出异常)。请注意,您可以更改add+=)和remove-=)以执行与默认行为不同的操作。

Jon Skeet有一个页面,解释了您可能想要阅读的delegates and events in C#

答案 1 :(得分:3)

第一个问题:是的,只要方法签名与事件的委托类型兼容,就可以这样做。

第二个问题:是的,你也可以这样做。使用EventTest.GetInvocationList()获取为您的活动注册的方法。然后分别使用-=+=删除并重新添加委托。请参阅以下示例:

  public class Test 
  {
        public event EventHandler EventTest = delegate { };
        public void Method()
        {
            //get registered event handlers
            Delegate[] invocationList = EventTest.GetInvocationList();

            //remove them
            foreach (Delegate d in invocationList)
            {
                EventTest -= (EventHandler)d;
            }

            //this method won't trigger anything, because 
            //invocation list is empty
            Method2();

            //re-add event handlers
            foreach (Delegate d in invocationList)
            {
                EventTest += (EventHandler)d;
            }
        }

        public void Method2()
        {
            if(EvenTest != null)
            EventTest(this, EventArgs.Empty);
        } 
   }

我删除了一些简单的Main() - 方法,使代码更具可读性。

答案 2 :(得分:2)

所以答案是肯定的,是的,并按顺序添加。

事件是MulticastDelegate类的实例。要找出分配给事件的代理,请在事件上调用GetInvocationList方法。见http://msdn.microsoft.com/en-us/library/system.multicastdelegate.getinvocationlist%28v=VS.71%29.aspx

这将为您提供一系列代表。因此,您可以调用GetInvocationList来获取现有的事件处理程序;然后从事件中清除事件处理程序;做一些动作;然后将处理程序重新分配给事件。

答案 3 :(得分:2)

代表在.NET中是“多播”,事件是类似属性的包装器。通过以长格式表示法观察事件,您可以获得更好的未成年:

private EventHandler _handler;

public event EventHandler MyEvent
{
  add { _handler = (EventHandler)Delegate.Combine(_handler, value);  }
  remove { _handler = (EventHandler)Delegate.Remove(_handler, value); }
}

您通常会在一行中写下以上所有内容:

public event EventHandler MyEvent;

要完成,事件会占用一个Invocationlist,它会在触发时按顺序处理。订单无法保证。

答案 4 :(得分:2)

只是为了掩盖一点,我认为任何人都没有明确地处理过,事件并非全部同时发生 - 它们按顺序发射......