1

我在 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);
        }
    }
}

//问候

4

2 回答 2

3

这似乎不太可能,但是只有在高度线程化的代码期间才会发生极端的边缘情况,即使这样也很少发生 - 但是从技术上讲,在您的实现中获得线程竞争是可能的。最好有:

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 
    }
}
于 2013-05-08T08:37:32.177 回答
1

如果您在大量多线程场景中使用控件, Marc Gravell指出了正确的方法和解决方案。有了这些清晰的知识,我很想知道当你第一次注意到这个空引用时你是否有任何订阅者。这是因为一个简单而基本的事实,如果您没有订阅者附加到该事件,您将获得空引用。

public event EventHandler<GameEventArgs> Pickedimage= delegate { };
于 2013-05-08T09:03:48.857 回答