2011-08-22 57 views
5

我的應用程序是C#和C++代碼的混合。用C#編寫的啓動模塊在初始化階段加載C++模塊,通過COM(組件對象模型)機制加載。所有工作正常,直到我決定向C#部分添加一個wcf服務。所有wcf服務調用都使用COM路由到C++代碼。添加一些新的方法後,我注意到輸出窗口中的內存泄漏。所以我添加了斷點到C++類的desctructor,從截圖中可以看出。從這一點上,奇怪的事情開始發生。程序到達斷點後意外崩潰。首先奇怪的是,當我運行沒有設置斷點的程序時,它會優雅地結束。第二個奇怪的是,程序崩潰的方式就好像它沒有調試器一樣運行。點擊按鈕「打開調試器」(或類似的東西)後,我收到錯誤消息:「程序已在調試器下打開。」無輸出窗口中的消息可能將我指向錯誤的來源,無可疑代碼。 將消息框添加到析構函數開始時,它會顯示小數秒,然後關閉整個應用程序(無需添加用戶讀取消息框中顯示的內容的機會)。拼命尋找任何線索。怪異崩潰調試COM對象的析構時

P.S.只有在調用wcf方法至少一次時纔會出現問題。不依賴於此特定調用中的程序流是否被路由到C++級別。

enter image description here

enter image description here

+0

嘗試使用,而不是與調試WinDbg中獲得關於崩潰彷彿奇蹟消失崩潰 – SpaceghostAli

回答

0

解決由以下代碼:

public void Dispose() 
{ 
    Marshal.Release(internal_interface_ptr); 
    internal_interface_ptr = IntPtr.Zero; 
    Marshal.ReleaseComObject(internal_interface); 
    Marshal.ReleaseComObject(internal_interface); 
    internal_interface = null; 
} 

除了這一個其它參考被掛在C++代碼。因此,爲了得出結論,我的主要錯誤是忘記了在C#代碼中顯式釋放COM對象。即使垃圾收集器執行管理內存的任務,對於用其他編程語言編寫的模塊也是如此。當從內存中卸載特定的動態鏈接庫時,COM析構函數被最近調用,這導致了問題。希望我明確解釋清楚。

1

當C中調用C#++有時垃圾回收器不能正常得到程序結束之前調用。嘗試在C#代碼的末尾強制垃圾收集。

+0

更多信息,不過節目結束之前,所有的COM析構函數完成了他們的工作。看到我的第二個截圖。在這個精確的時刻,程序就在它完成之前,但是一些我們尚未調用的COM析構函數。他們被稱爲他們的工作後,突然完成。 – truthseeker

+0

解決下面的代碼: public void Dispose() { Marshal.Release(internal_interface_ptr); internal_interface_ptr = IntPtr.Zero; Marshal.ReleaseComObject(internal_interface); internal_interface = null; } – truthseeker

+0

我不太清楚你的意思是「崩潰就好像奇蹟消失了」。我想你可能需要強制你的服務在調用garbase收集器之前進行處理。檢查以確保在Garbase收集器運行之前處理了ServicesToRun或服務,否則運行會對你沒有好處。 – mydogisbox