簡體   English   中英

如何恢復尚未正確釋放的COM對象?

[英]How to recover COM objects which have not been properly released?

當有人使用任務管理器結束已實例化COM對象的.NET進程時,AFAIK無法using {}或事件處理塊在try {} finally {}調用Marshal.FinalReleaseComObject

下次啟動應用程序時,COM對象處於不可用狀態,我需要重新啟動計算機以使其再次運行。

我使用Marshal.BindToMoniker來實例化對象。

我做錯了什么,有什么我錯過的嗎?


我試過了賽義德的建議,但它沒有用

private const int WM_CLOSE = 0x0010;

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_CLOSE)
    {
        logger.Info("WM_CLOSE");
        Marshal.FinalReleaseComObject(comObject);
    }

    base.WndProc(ref m);
}

你可能不需要。 當垃圾收集器到處釋放內存時,它會檢查對象是否有一個尚未被調用的Dispose()方法。 如果尚未調用Dispose()方法,它將調用它。

我在一個控制台應用程序中對此進行了測試,並在我的Dispose功能中發出了3個揚聲器。 退出應用程序后,無需在對象上調用Dispose,大約需要30秒才能聽到3聲嘟嘟聲。 時間是決定性的。

當然,必須正確編碼對象。

您是否在關機后立即運行應用程序? 為什么不等幾分鍾看它是否有效?

編輯:我假設您在Dispose函數中有Marshal.FinalReleaseComObject。

任務管理器使用的是本機等效的Process.Kill (或者可能更強大的東西)。 請注意文檔中的這個敘述:

Kill強制終止進程,而CloseMainWindow僅請求終止。

...

調用CloseMainWindow發送請求以關閉主窗口,該窗口在格式良好的應用程序中...

和,

如果您致電Kill則由流程編輯的數據或分配給流程的資源可能會丟失。 Kill導致異常進程終止,僅在必要時使用。

簡而言之,在程序代碼中沒有什么可以做的,以防止這種情況發生 - 插頭已被拉動。 不會發送任何窗口消息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM