2012-08-25 18 views
22

我有一個擁有大量靜態成員的類,其中一些保持對託管和非託管對象的引用。如何以及何時處置c#靜態成員?

例如,一旦引用Type,就會調用靜態構造函數,這會導致我的類旋轉任務的blockingQueue。例如,當一個靜態方法被調用時會發生這種情況。

我實現了IDisposable,它給了我處理我創建的任何實例對象的方法。但是,如果消費者不從我的類創建任何實例對象,則永遠不會調用這些方法。

如何以及在哪裏放置代碼來處理由我的類的靜態部分維護的引用?我一直認爲當最後一個實例對象被釋放時,處理靜態引用的資源會發生;這是我第一次創建一個沒有實例創建的類。

+1

靜態項目可用於應用程序的整個執行。您不使用NEW關鍵字創建靜態項目,所以這意味着您沒有任何事件的多個實例,因爲您實際上不會實例化任何內容。關於被管理對象,不用擔心,GC會照顧他們。關於非託管資源嘗試在非靜態類中使用它們,否則它們將一直保留,直到您關閉應用程序。靜態項目不支持處置。 – alexandrudicu

+0

謝謝。看起來我需要在這裏重新考慮我的設計。 – Joe

回答

35

你的類的靜態變量不會被垃圾收集,直到託管你的類的應用程序域被卸載。 Dispose()方法不會被調用,因爲它是一個實例方法,並且你說你不會創建你的類的任何實例。

如果您想要使用Dispose()方法,請將您的對象設置爲單例,創建它的一個實例,並在您的應用程序即將退出時將其明確處置。

public class MyClass : IDisposable { 
    public IList List1<int> {get; private set;} 
    public IDictionary<string,string> Dict1 {get; private set;} 
    public void Dispose() { 
     // Do something here 
    } 
    public static MyClass Instance {get; private set;} 
    static MyClass() { 
     Instance = new MyClass(); 
    } 
    public static void DisposeInstance() { 
     if (instance != null) { 
      Instance.Dispose(); 
      Instance = null; 
     } 
    } 
} 
+0

這是有道理的。我懷疑我可能不得不最終使用Singleton模式......感謝您的幫助。 – Joe

0

您應該手動處理這些對象,無法爲靜態資源創建「終結器」。

+1

我將如何手動處理它們?我將如何得到通知我需要這樣做? – Joe

+0

@Joe這完全取決於你自己決定。只有你知道什麼時候該調用靜態存儲的東西了。 – vcsjones

+0

例如,請參閱原始問題中的示例,其中我啓動了ActionsQueueQueue。應該運行此隊列,直到用戶不再想要將動作放入它爲止(通過靜態方法)。 讓我說得更清楚;我什麼時候才能完成排除隊列的任務? 那麼,我什麼時候殺了它?我如何知道我的班級不再處於用戶的「範圍」? – Joe

0
public class Logger : IDisposable 
{ 

    private string _logDirectory = null; 
    private static Logger _instance = null; 

    private Logger() : this(ConfigurationManager.AppSettings["LogDirectory"]) 
    { 
     AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit; 
    } 

    private Logger(string logDirectory) 
    { 
    } 

    public static Logger Instance 
    { 
     get 
     { 
      if (_instance == null) 
       _instance = new Logger(); 
      return _instance; 
     } 
    } 

    private void CurrentDomain_ProcessExit(object sender, EventArgs e) 
    { 
     Dispose(); 
    } 



    public void Dispose() 
    { 
     // Dispose unmanaged resources 
    } 
}