2013-05-08 95 views
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); 
     } 
    } 
} 

//問候

+0

小觀察:爲什麼在構造函數中引發一個事件?根據定義,沒有調用代碼已經獲得對該對象的引用,所以沒有人可能*在此時訂閱了該事件... – 2013-05-08 08:44:32

回答

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 
    } 
} 
1

馬克Gravell指出了正確的方法和解決方案的情況下,如果您使用的是控制在重多線程場景。有了這些清晰的知識,我很想知道當你第一次注意到這個空引用時你是否有任何訂閱者。這是爲了簡單和基本的事實,如果沒有訂閱者附加到該事件,您將獲得空引用。

public event EventHandler<GameEventArgs> Pickedimage= delegate { }; 
+0

我已經在form1中的一個控件實例中訂閱了它。 control.PickedImage + = onPickedImage;還有一種叫做onPickedImage()的方法。 – user1501127 2013-05-08 09:44:18

+0

我把代碼移到了另一個類,它的工作原理非常好。我非常好奇它爲什麼不在用戶控件中觸發。 – user1501127 2013-05-14 19:37:46