2010-06-22 69 views
2

有問題:我創建包裝PerformanceCounter對象的單例助手對象。它實現了IDisposable ...但是現在我發現,當我關閉測試樣本控制檯主機應用程序時,計數器仍然在perfmon工具中可見(生產中我將託管在Windows服務中),並且仍在運行。如何在應用程序崩潰時處理

我想到Dispose在終結器中被調用,但是我沒有處理託管資源 - 它們是PerformanceCounter對象。我該怎麼做才能確保資源得到適當的釋放?

謝謝你,帕維爾

回答

1

這是性能計數器的正常行爲。即使沒有進程爲它們生成數據,它們也是存在的全球「對象」。例如,您可以選擇.NET perf計數器之一,即使機器上沒有運行單個.NET程序。如果計數器正在主動生成數據,即使您沒有正在運行的進程來更新其值,那麼您可能選擇了不適當的CounterType。

查看InstanceLifetime屬性以查看過程值是否適合您的計數器。

+0

這就是我一直在尋找的。我的計數器嚴格與實例相關,並且在進程退出時應該丟棄。 什麼是模式我使用MultiInstance方法。 謝謝! – dragonfly 2010-06-23 08:45:52

+0

呃,我很高興早點:)櫃檯的InstanceLifetime是Global。但我不知道,如何將其更改爲過程:/ 任何想法? – dragonfly 2010-06-23 09:02:44

+0

例外: 實例初始化後,InstanceLifetime無法設置。在設置RawValue之前,您必須使用默認構造函數並手動設置CategoryName,InstanceName,CounterName,InstanceLifetime和ReadOnly屬性。 – dragonfly 2010-06-23 09:09:11

1

檢查下面的代碼,看看如果你使用一次性模式。終結者應該明確地調用你的dispose方法。

class DisposableObject : IDisposable 
{ 
    public void Dispose() 
    { 
     this.Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    protected void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      // dispose managed resources 
     } 
     // dispose unmanaged resources 
    } 

    ~DisposableObject() 
    { 
     this.Dispose(false); 
    } 
} 
+0

Yeap。我遵循那種模式,真正的配置代碼在 //配置管理資源 評論。所以當應用程序粉碎終結器被稱爲和處置設置爲false。 – dragonfly 2010-06-22 12:09:18

+0

@dragonfly - 如果您的應用程序崩潰,則不能保證終結器被調用。請參閱object.Finalize方法的備註部分:http://msdn.microsoft.com/en-us/library/system.object.finalize.aspx – tvanfosson 2010-06-22 12:30:01

+0

甚至更​​好:) thx。 – dragonfly 2010-06-23 09:18:47

2

如果您的應用程序崩潰了,那麼確保非託管資源的處置方式就不多了。您應該正確實施一次性模式,並在您的非託管資源完成後處置(如果尚未完成)。通過這種方式,當服務關閉時您將釋放資源,但在發生硬件崩潰時,您的代碼可能無法運行。

我會建議,特別是如果您在Windows服務中託管可能會自動重新啓動您的代碼,您編寫代碼的期望可能會崩潰,將非託管資源留在並重用/回收它們可能。除此之外,你的編程也應該非常防守,以確保任何崩潰是罕見的(並且超出你的控制範圍)。