由于空引用,订阅事件未触发
本文关键字:事件 于空 引用 | 更新日期: 2023-09-27 18:12:51
我在toPickedImage方法中得到空引用错误,我不明白为什么会这样。任何人都可以帮助我解释为什么我收到这个错误。
任何和所有的帮助将不胜感激!
代码如下:
public partial class ownGUI : UserControl
{
private string m_id;
private int m_value;
public event EventHandler<GameEventArgs> Pickedimage;
public ownGUI()
{
InitializeComponent();
}
public ownGUI(String id, int value)
{
InitializeComponent();
m_id = id;
m_value = value;
GameEventArgs image = new GameEventArgs(m_id, m_value);
toPickedimage(image);
}
public void toPickedimage(GameEventArgs e)
{
if (Pickedimage != null)
{
Pickedimage(this, e);
}
}
}
//问候
这似乎不太可能,但有一个极端的情况只会发生在高线程代码中,甚至很少发生-然而在技术上是可能的在您的实现中获得线程竞争。最好是:
var handler = Pickedimage
if(handler != null) handler(this, e);
然而!我认为更有可能是订阅的事件由于订阅者中的错误而引发此错误。查看堆栈跟踪来找出答案。如果您想过分地保护事件(这样即使有坏订阅者,它也不会失败),那么像这样:
var handler = Pickedimage;
if(handler != null) {
foreach (EventHandler<GameEventArgs> subscriber in
handler.GetInvocationList())
{
try {
subscriber(this, e);
} catch (Exception ex) {
Trace(ex);
}
}
}
作为一个脚注,我个人我会推迟创建GameEventArgs
,直到你知道你有一个关心的人,例如:
protected virtual void OnPickedimage(int id, int value)
{
var handler = Pickedimage;
if(handler != null) {
var e = new GameEventArgs(id, value);
//... and invoke it
}
}
Marc Gravell指出了正确的方法和解决方案,如果你在多线程场景中使用你的控件。有了这些清晰的知识,我很想知道,当您第一次注意到这个空引用时,您的事件是否有任何订阅者。这是为了一个简单而基本的事实,即如果您没有将订阅者附加到该事件,则将获得空引用。
public event EventHandler<GameEventArgs> Pickedimage= delegate { };