[英]Calling an event handler in C#
I've been trying to learn how to use event handlers in C# but I can't figure out what handler(this, e) does in the following code: 我一直在努力学习如何在C#中使用事件处理程序,但我无法弄清楚以下代码中的处理程序(this,e):
public event EventHandler ThresholdReached;
protected virtual void OnThresholdReached(EventArgs e)
{
EventHandler handler = ThresholdReached;
if (handler != null)
{
handler(this, e);
}
}
Is it trying to call the event handler method (this) with the event (e)? 它是否尝试使用事件(e)调用事件处理程序方法(this)?
It invokes all registered event listeners which are registered on the ThresholdReached
event. 它调用在
ThresholdReached
事件上注册的所有已注册事件侦听器。
The handler != null
check makes sure at least one listener is registered to that event. handler != null
check确保至少有一个侦听器注册到该事件。
In C# 6.0 and above you can use Null Propagation : 在C#6.0及更高版本中,您可以使用Null Propagation :
handler?.Invoke(this, e);
handler(this, e)
will call every registered event listener. handler(this, e)
将调用每个注册的事件监听器。 Event listeners subscribe with help of the +=
operator and unsubscribe with -=
operator to that event. 事件侦听器在
+=
运算符的帮助下订阅,并使用-=
运算符取消订阅该事件。
this
is there to give the event listener to know who raised the ThresholdReached event. this
是为了让事件监听器知道谁提出了ThresholdReached事件。 Who was the sender of the event. 谁是活动的发送者。
e
is the event argument which is also passed into the listener method which can contain more useful informations about the ThresholdReached event eg which threshold was reached. e
是事件参数,它也传递给侦听器方法,该方法可以包含有关ThresholdReached事件的更多有用信息,例如达到了哪个阈值。
It is raising a ThresholdReached
event with arguments sender=this and eventarguments = e. 它使用参数sender = this和eventarguments = e引发
ThresholdReached
事件。 In fact, it is the same as the following; 实际上,它与以下相同;
public event EventHandler ThresholdReached;
protected virtual void OnThresholdReached(EventArgs e)
{
if (ThresholdReached != null)
{
ThresholdReached(this, e);
}
}
If there are any listeners to this event; 如果有任何听众参加此活动; it will simply call listener delegates;
它只会调用监听器代理;
this.ThresholdReached += new EventHandler(Form1_ThresholdReached);
Then, when this event is raised Form1_ThresholdReached
function will be called with this
and e
parameters. 然后,当引发此事件时,将使用
this
和e
参数调用Form1_ThresholdReached
函数。
The code in your example copies all registered handlers to the local variable handler
, checks that the invocation list is not empty and invokes all members of the copied invocation list with the arguments this
and e
. 示例中的代码将所有已注册的处理程序复制到本地变量
handler
,检查调用列表是否为空,并使用参数this
和e
调用复制的调用列表的所有成员。
The reason for the fact that you get a snapshot of the current invocation list is that delegates are immutable . 您获得当前调用列表的快照的原因是委托是不可变的 。 You get a reference to the current multicast delegate, and when handlers are added or removed the backing field points to a new delegate created from two immutable ones.
您将获得对当前多播委托的引用,并且在添加或删除处理程序时,支持字段指向从两个不可变的委托创建的新委托。
The usual reason to copy the invocation list to a local variable is some form of thread-safety: a handler could be unsubscribed between the usual nullity check (check that the invocation list isn't empty) and the actual invocation: that way you might accidentally fire an event with no handlers and a NullReferenceException
would be thrown. 将调用列表复制到局部变量的通常原因是某种形式的线程安全:处理程序可以在通常的无效性检查(检查调用列表不为空)和实际调用之间取消订阅:这样你可能会意外触发没有处理程序的事件,并抛出
NullReferenceException
。
Is it trying to call the event handler method (this) with the event (e)?
它是否尝试使用事件(e)调用事件处理程序方法(this)?
No, not literally. 不,不是字面上的。 It is calling the event handler with the
EventArgs
e and using this
as sender. 它调用与事件处理程序
EventArgs
e和使用this
发件人。 It might as well be: 它可能是:
if (ThresholdReached != null)
{
ThresholdReached(this, e);
}
Or, to circumvent the null check: 或者,绕过空检查:
public event EventHandler ThresholdReached = delegate { };
protected virtual void OnThresholdReached(EventArgs e)
{
ThresholdReached(this, e);
}
But, as @Oded noted, the first piece isn't thread-safe, because EventHandler handler = ThresholdReached
creates a copy of the handler, which is better explained in this question . 但是,正如@Oded所指出的那样,第一部分不是线程安全的,因为
EventHandler handler = ThresholdReached
创建了一个处理程序的副本,在这个问题中可以更好地解释。
handler
refers to your ThresholdReached
event. handler
指的是您的ThresholdReached
事件。 So, if anyone is subscribing to ThresholdReached
events, their registered handler will be called with arguments this
and e
. 因此,如果有人订阅了
ThresholdReached
事件,则将使用参数this
和e
调用其注册的处理程序。
It is Triggering the ThresholdReached
event. 它是触发
ThresholdReached
事件。 Passing a reference to itself, this
. 通过对自身的引用,
this
。 Passing arguments about the event in e
. 在
e
传递关于事件的论点。
The call to handler represents a function call in another object or class. 对handler的调用表示另一个对象或类中的函数调用。 When you create the object, you will be able to write a piece of code that looks like this:
创建对象时,您将能够编写一段如下所示的代码:
obj.ThreasholdReached += new EventHandler(someFunction);
someFunction
in that class will be defined like this someFunction
中的someFunction
将被定义为这样
public someFunction(object sender, EventArgs e) {...}
the OnThreasholdReached
function in the original object is what publishes the event to any other class that has assigned a function to the ThreasholdReached handler. 原始对象中的
OnThreasholdReached
函数将事件发布到已为ThreasholdReached处理程序分配函数的任何其他类。 Using handler
as a go-between is an entirely unnecessary extra step. 使用
handler
作为中间人是一个完全不必要的额外步骤。 You are still saying if ThreasholdReached != null
, its the same thing. 你还在说
if ThreasholdReached != null
,它是一样的。
In Summary: The line of code handler(this, e)
is actually the call to whatever subscriber someFunction(object sender, EventArgs e)
has been assigned to the ThreasholdReached event of the object. 总结:代码
handler(this, e)
实际上是对任何订户someFunction(object sender, EventArgs e)
已分配给对象的ThreasholdReached事件的调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.