我一直在努力学习如何在C#中使用事件处理程序,但我无法弄清楚以下代码中的处理程序(this,e):
public event EventHandler ThresholdReached;
protected virtual void OnThresholdReached(EventArgs e)
{
EventHandler handler = ThresholdReached;
if (handler != null)
{
handler(this, e);
}
}
是否尝试使用事件(e)调用事件处理程序方法(this)?
答案 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_ThresholdReached
和this
参数调用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
个事件,则会使用参数this
和e
调用其注册的处理程序。
答案 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事件的调用。