2012-04-19 45 views
1

我的混合模式MFC應用程序正在創建錯誤的內存泄漏,因爲在MFC dll關閉之前CRT沒有時間關閉。混合模式C++/CLI應用程序沒有正確關閉CLR

我有一個非常簡單的小應用程序,顯示問題:

#include <windows.h> 
#include <iostream> 

struct LongTimeToDestroy 
{ 
    ~LongTimeToDestroy() 
    { 
    std::cout << "Will get called!" << std::endl; 
    Sleep(3000); 
    std::cout << "Won't get called!" << std::endl; 
    } 
}; 

LongTimeToDestroy gJamsUpTheCRT; 

int main() 
{ 
} 

編譯cl.exe /clr test.cpp。在運行時,你會得到:

Will get called! 

問題的癥結是:gJamsUpTheCRT之前,宣稱任何靜態/全局變量不會被釋放。例如,在我的情況下,MFC CWinApp派生的類不會被清理。

這是預期的行爲?我想讓我的應用完全關閉。

感謝,

回答

2

這是預期的行爲嗎?

是的,儘管您必須閱讀CLI規範中的精美打印。它承諾程序終止時調用託管對象的終結器。但有一點需要注意,這樣做的終結者線程需要兩秒鐘才能完成工作。如果需要更長的時間,那麼CLR會假設有一些嚴重錯誤。就像在無法獲得信號的同步對象上進行代碼阻塞的常見詛咒一樣。它由處理終止器線程並允許程序終止。沒有診斷。

你必須解決這個限制。

+0

Porges鏈接中提供的Joe Duffy鏈接指出:「雖然可配置,但默認情況下CLR會讓終結器運行2秒」。你知道如何配置這個嗎? – Cechner 2012-04-19 00:52:10

+0

否。除了自己託管CLR,也許。實際上,當你的終結者已經燒掉了50億個CPU週期並且沒有完成工作,那麼增加一些更不可能帶來救濟。 – 2012-04-19 01:10:00

1

我相信this answers your problem

相關的文字:

雖然配置,默認情況下,CLR會讓終結了越來越不耐煩2秒之前的運行;如果超過此超時,終止器線程將停止,並且關閉繼續,而不會耗盡終止器隊列的其餘部分。

所以你真的不應該有任何析構函數執行任務,需要時間。

編輯:其實,這不是一個CLR類,所以它不應該在最終化隊列?這可能是誤導。

+0

這看起來極端 - 這怎麼配置?我猜我的情況(MFC靜態鏈接到C++/CLI庫)並不常見 - 如果我把所有的C++/CLI的東西放入MFC DLL並鏈接到該DLL,這是否會糾正? – Cechner 2012-04-19 00:34:42

+0

只需要進一步注意你的編輯:看起來CRT清理是由主模塊'.cctor'處理的,我想這個清理是在'finalizer queue'中的某處。 – Cechner 2012-04-19 00:56:49

相關問題