[英]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.