2012-03-26 17 views
0

我很想知道,在下面的代碼中,靜態實例是否可能是非空的,但MYDB類引用被GAC處置並設置爲null?靜態實例的對象引用問題

public class DA_Setting 
{ 
    private static readonly DA_Setting instance = new DA_Setting(); 

    public static DA_Setting Instance 
    { 
     get { return instance; } 
    } 

    db MYDB = new db(); 

    // Some other methods here 

    private void Getname() 
    { 
     MYDB.GetNames(); // Sometimes this line throws null reference error on LIVE server. 
    } 
} 
+0

instance.MYDB.GetNames()? – Goran 2012-03-26 07:57:38

+0

它進行數據庫調用。 – 2012-03-26 07:58:53

+2

查看(或顯示)異常的堆棧跟蹤。 – Heinzi 2012-03-26 08:04:49

回答

3

GC永遠不會設置某種東西null。期。

如果你有一個對象的引用,GC的設計目的是看你仍然在使用該對象,通過該引用保留它,因此在你完成它之前不會收集它。

MYDB場是null的唯一方法是,如果你沒有一個值分配給它(我可以看到你在你的代碼,防止場景的初始化),或者如果您分配的null值在代碼稍後的某個時間點到現場。

我建議你把MYDB成只得到屬性並在類的構造函數初始化:

private DA_Setting() 
{ 
    this.MYDB = new db(); 
} 

public db MYDB { get; private set; } 

這將確保你不能在類的外部設置這個值,應該給你一個更更可預測的類型。

+0

感謝您的幫助! – 2012-03-27 02:38:36

+0

如果這有助於解決您的問題,請做好標記,作爲您的問題的「接受」答案。如果沒有,請用更多信息更新您的問題,我們可以嘗試進一步幫助您。 – 2012-03-27 06:31:58

+0

「GC永遠不會設置任何東西爲空」的陳述事實上是不正確的。在做出分類陳述之前,它通常會檢查事實。在GC期間,http://msdn.microsoft.com/en-us/library/system.weakreference.aspx WeakReference類的'Target'屬性可以*設置爲'null'。 – 2012-03-27 07:19:38

1

如果GC仍然可以訪問並且可以訪問,GC將不會收集該字段。我猜其他一些對象是null。你有沒有嘗試進入代碼,也許在GetNames方法?

你的靜態變量是一個GC根,這意味着只要你的Application/AppDomain運行,它就不會被收集。該字段是GC根目錄的字段,因此應該無法收集該字段。看到這裏有關垃圾收集的更多信息:http://www.simple-talk.com/dotnet/.net-framework/understanding-garbage-collection-in-.net/

+0

你確定嗎? – 2012-03-26 08:04:41

+0

是的,如果GC在你的程序運行時只會竊取你的變量,那真的很糟糕,不是嗎?我確定空引用錯誤在其他地方,很可能在GetNames方法中。嘗試進入它。或者查看異常附帶的堆棧跟蹤。 – Botz3000 2012-03-26 08:15:27

+0

感謝您的幫助! – 2012-03-27 02:38:45

1

這應該不會發生,因爲我明白了。靜態初始化器和構造器在訪問靜態成員之前運行 - 這由C#文檔承諾。實例初始化程序使用實例構造函數運行,因此如果您調用DA_Setting.Instance.Getname(),那麼應該永遠不會有空引用。垃圾收集器不會隨機出現並處理你仍然參考的東西,而且你肯定還有一個參考,因爲靜態成員沒有生命週期結束,而應用程序仍然運行。

你檢查了是什麼導致空引用異常?難道它是db實例內的東西?

+0

那麼日誌跟蹤的位置,顯示對象引用爲空。因爲你們都說GC不會配置一個類的靜態實例持有的引用,那麼我的下一步就是在我的LIVE服務器上運行sql profiler並檢查它返回的參數和值。 – 2012-03-26 08:16:06