在C#中调用事件处理程序

时间:2012-08-31 14:40:21

标签: c# events

我一直在努力学习如何在C#中使用事件处理程序,但我无法弄清楚以下代码中的处理程序(this,e):

public event EventHandler ThresholdReached;

protected virtual void OnThresholdReached(EventArgs e)
{
    EventHandler handler = ThresholdReached;
    if (handler != null)
    {
        handler(this, e);
    }
}

是否尝试使用事件(e)调用事件处理程序方法(this)?

7 个答案:

答案 0 :(得分:3)

它会调用在ThresholdReached事件中注册的所有已注册事件侦听器。

handler != null检查确保至少有一个侦听器已注册到该事件。

在C#6.0及以上版本中,您可以使用Null Propagation

handler?.Invoke(this, e);

handler(this, e)将调用每个注册的事件监听器。事件监听器在+=运算符的帮助下订阅,并使用-=运算符取消订阅该事件。

this可以让事件监听器知道是谁引发了ThresholdReached事件。谁是活动的发送者。

e是事件参数,它也被传递给侦听器方法,该方法可以包含有关ThresholdReached事件的更多有用信息,例如: 已达到阈值。

答案 1 :(得分:1)

它使用参数sender = this和eventarguments = e引发ThresholdReached事件。 实际上,它与以下内容相同;

public event EventHandler ThresholdReached;

protected virtual void OnThresholdReached(EventArgs e)
{
    if (ThresholdReached != null)
    {
        ThresholdReached(this, e);
    }
}

如果有任何听众参加此活动;它只会调用监听器代理;

this.ThresholdReached += new EventHandler(Form1_ThresholdReached);

然后,当引发此事件时,将使用Form1_ThresholdReachedthis参数调用e函数。

答案 2 :(得分:1)

示例中的代码将所有已注册的处理程序复制到本地变量handler,检查调用列表是否为空,并使用参数this和{{调用复制的调用列表的所有成员1}}。

您获得当前调用列表快照的原因是delegates are immutable。您将获得对当前多播委托的引用,并且在添加或删除处理程序时,支持字段指向从两个不可变的委托创建的新委托。

将调用列表复制到局部变量的通常原因是某种形式的线程安全:处理程序可以在通常的无效性检查(检查调用列表不为空)和实际调用之间取消订阅:如果您不小心触发没有处理程序的事件,则会抛出e

答案 3 :(得分:0)

  

是否尝试使用事件(e)调用事件处理程序方法(this)?

不,不是字面意思。它使用EventArgs e调用事件处理程序并使用this作为发件人。它可能也是:

if (ThresholdReached != null)
{
    ThresholdReached(this, e);
}

或者,绕过空检查:

public event EventHandler ThresholdReached = delegate { };

protected virtual void OnThresholdReached(EventArgs e)
{
    ThresholdReached(this, e);
}

但是,正如@Oded所说,第一部分不是线程安全的,因为EventHandler handler = ThresholdReached创建了一个处理程序的副本,这在this question中有更好的解释。

答案 4 :(得分:0)

handler是指您的ThresholdReached事件。因此,如果有人订阅ThresholdReached个事件,则会使用参数thise调用其注册的处理程序。

答案 5 :(得分:0)

触发ThresholdReached事件。传递对自身的引用,this。在e

中传递有关该事件的论据

答案 6 :(得分:0)

对handler的调用表示另一个对象或类中的函数调用。创建对象时,您将能够编写一段如下所示的代码:

obj.ThreasholdReached += new EventHandler(someFunction);
该类中的

someFunction将像这样定义

public someFunction(object sender, EventArgs e) {...}

原始对象中的OnThreasholdReached函数将事件发布到已为ThreasholdReached处理程序分配函数的任何其他类。使用handler作为中间人是一个完全不必要的额外步骤。你仍在说if ThreasholdReached != null,它是一样的。

摘要:代码行handler(this, e)实际上是对订阅者someFunction(object sender, EventArgs e)已分配给对象的ThreasholdReached事件的调用。