考虑“应用程序”,其中一个对象(Thrower)将球投掷到另一个对象(Receiver)。球被抛出时会发生事件(BallIsThrowed)。
以下是2个班级:
然后是切入点:
最后,当事件被触发时,委托指向的方法:
这很好用。
现在我想评论这一行:
因为我想说球没被抛出。
结果为null异常:
这是正常的,因为此时BallIsThrowed为空
为了解决这个问题,我启动了我的活动:
但后来我的问题是我的代码永远不会在我退出“receiver.Register(thrower)”
我的问题是: 如何激活2方法EventMethod?
答案 0 :(得分:4)
触发事件的最佳做法是:
EventHandler ballIsThrowed = BallIsThrowed;
if (ballIsThrowed != null)
{
ballIsThrowed(this, EventArgs.Empty);
}
临时变量的原因是为了防止空检查和执行之间的竞争条件。
答案 1 :(得分:0)
忍受我:你正在为BallIsThrowed设置一个事件处理程序,然后使用IthrowTheBall()来实际触发事件,使用以下代码:
BallIsThrowed(this, EventArgs.Empty);
当您尝试调用事件处理程序时,在这种情况下是BallIsThrowed,它必须存在或者它将抛出NullReferenceException。因此,为了使其工作,它必须存在一个事件处理程序BallIsThrowed。实际上,直到你评论这一行:
//BallIsThrowed += new EventHandler(method.EventMethod2);
所以基本上你需要在激活之前验证EventHandler是否存在:
if(BallIsThrowed!= null) BallIsThrowed(this,EventArgs.Empty);
答案 2 :(得分:0)
另一种(更优雅,如果你问我)这样做的方式是:
(BallIsThrowed??delegate{})(this, EventArgs.Empty);
紧凑,线程安全......
答案 3 :(得分:0)
有两件事需要纠正:
在您的事件调用者中,请检查EventHandler != null
,因为您不知道是否有人注册了您的处理程序。
var ballThrown = BallIsThrowed;
if (ballThrown != null)
{
ballThrown(this, EventArgs.Empty);
}
一般情况下,为了向您的帐户注册多个delegate
EventHandler
,不要通过=
运算符注册,而是通过。{
+=
运算符,表示您想要附加新的delegate
:
public void IThrowTheBall()
{
// Do stuff
// You dont have to register this delegate, you can append it to the current
// delegates already registered
BallIsThrowed += method.EventMethod1;
}