我一直在修復winforms應用程序中的一些內存泄漏問題,並注意到一些不顯式放棄的對象(開發人員沒有稱爲Dispose方法)。 Finalize方法的實現也沒有幫助,因爲它不在if (disposing)
子句中。所有的靜態事件註銷和收集清除已放入if (disposing)
條款。最好的做法是調用的Dispose如果對象是一次性的,但不幸的是如果有非託管對象,靜態的事件處理程序和需要處置時,清除一些管理的集合這種情況有時一次性實現 - 應該如何處理'if(disposing)'
。有什麼方法可以決定什麼應該進入以及應該從if (disposing)
條款中排除。
// Dispose(bool disposing) executes in two distinct scenarios.
// If disposing equals true, the method has been called directly
// or indirectly by a user's code. Managed and unmanaged resources
// can be disposed.
// If disposing equals false, the method has been called by the
// runtime from inside the finalizer and you should not reference
// other objects. Only unmanaged resources can be disposed.
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Free other state (managed objects).
}
// Free your own state (unmanaged objects).
// Set large fields to null.
disposed = true;
}
}
It says管理對象應在if (disposing)
通常只有執行時顯式調用Dispose方法由開發商。如果Finalize方法已經實現並且開發人員忘記調用Dispose方法,那麼通過Finalizer進行的執行不在if (disposing)
部分。
以下是我的問題。
如果我有導致內存泄漏的靜態事件處理程序,我應該在哪裏取消註冊它們?有沒有
if (disposing)
條款?如果我有一些導致內存泄漏的集合,我應該在哪裏清除它們?有沒有
if (disposing)
條款?如果我使用第三方的一次性對象(例如:devExpress winform控件),我不確定它們是託管對象還是非託管對象。假設我想在處理表單時處理它們。我怎麼知道什麼是管理的,什麼是非管理對象?一次性使用不是這樣說的嗎?在這種情況下,如何確定應該進入哪些內容以及從
if (disposing)
條款中應該列出哪些內容?如果我不確定某件事情是否管理或不受管理,那麼
if (disposing)
子句中處理/清除/取消註冊事件的不良後果是什麼?假設它在處置之前檢查爲空?
編輯
我的意思是事件未登記是一樣的東西下面。 Publisher是一個長期存在的實例,下面一行是訂閱者的構造函數。在這種情況下,用戶需要取消註冊該事件並在發佈者之前進行處置。
publisher.DoSomeEvent += subscriber.DoSomething;
實例訂閱靜態事件並不罕見。這些實例應該在if(Disposing)子句中取消訂閱。 – supercat