我只需要提出一个自定义事件,我想实现它。
这是界面:
public delegate void Back();
interface IGoBack
{
event Back GoBack;
void ExecuteGoBack();
}
这是一个有效的实施方案:
public partial class LiveView : UserControl, IGoBack
{
public LiveView()
{
InitializeComponent();
}
public event Back GoBack;
public void ExecuteGoBack()
{
GoBack();
}
private void btnGoBack_Click(object sender, EventArgs e)
{
ExecuteGoBack();
}
}
这不起作用(事件除外指针):
public partial class ViolationsControl : UserControl, IGoBack
{
public ViolationsControl()
{
InitializeComponent();
}
public event Back GoBack;
public void ExecuteGoBack()
{
if(GoBack!=null)GoBack();
}
private void btnGoBack_Click(object sender, EventArgs e)
{
ExecuteGoBack();
}
}
你认为我做错了什么?
答案 0 :(得分:2)
举办活动通常是这样实施的:
public void RaiseGoBack()
{
var handler = GoBack;
if(handler == null)
return;
handler();
}
这种实现的原因是线程安全。在您的代码中,有人可能已经 if
之后分离了最后一个处理程序,而之前实际调用了它。在这种情况下,尽管您进行了检查,GoBack
仍为null
上面的实现通过获取当前连接的处理程序的“快照”并对此快照执行检查和调用来解决此问题。
话虽如此,您需要附加调试器或检查堆栈跟踪以验证NullReferenceException
的确切位置。我上面概述的问题是所谓的竞争条件。如果你没有大量使用多个线程,通常不会发生这种情况
这意味着您的异常很可能是由其他地方引起的,很可能是在其中一个事件处理程序中。