一段時間以來,我在Visual Studio 2010的VSIX包中觀察到間歇性COM問題。嘗試訂閱IDE的基於COM的事件接收器之一隨機拋出以下錯誤:VSIX中令人討厭的COM互操作問題
「已從與其基礎RCW分開COM對象不能使用」
甲REPRO情況歸結爲代碼(它必須在VSIX使用,很明顯):
using System;
using EnvDTE;
using EnvDTE80;
class Test
{
private readonly Events _events;
private readonly Events2 _events2;
private readonly BuildEvents _buildEvents;
private readonly ProjectItemsEvents _projectItemsEvents;
public Test(IServiceProvider provider)
{
var dte = (DTE)provider.GetService(typeof(DTE));
var dte2 = (DTE2)dte;
// Store all references in fields as a GC precaution.
_events = dte.Events;
_events2 = (Events2)dte2.Events;
_buildEvents = _events.BuildEvents;
_projectItemsEvents = _events2.ProjectItemsEvents;
// Proceed to subscribe to event sinks.
_buildEvents.OnBuildBegin += BuildBeginHandler; // BOOM!
_projectItemsEvents.ItemAdded += ItemAddedHandler;
}
private void ItemAddedHandler(ProjectItem projectItem) { }
private void BuildBeginHandler(vsBuildScope scope, vsBuildAction action) { }
}
I已經從可以在網上找到的類似問題的大量描述中瞭解到可能的原因。這基本上是在COM互操作期間Runtime Callable Wrappers和GC交互方式的副作用。這是一個link到一個類似的問題完整的解釋。
我很好解釋,特別是因爲它建議一個簡單的解決方法 - 將事件接收器參考存儲在字段中,以防止過早GC。事實上,很多人似乎都以這種方式解決了他們的問題。
困擾我的是它不適用於我的情況。爲什麼我真的很難過。正如您可以清楚地看到的,我已經將所有對象引用存儲在字段中作爲預防措施。但錯誤仍然存在。我試圖在ctor結束時使用GC.KeepAlive()
更加明確,但無濟於事。還有什麼可以做的嗎?
沒有解決方案,我的VSIX隨機加載失敗,只留下一個選項:重新啓動Visual Studio,並希望下次不會發生這種情況。
任何幫助將真正被讚賞!
感謝您告訴您的解決方案。並不完全是我想聽到的,但是如果我沒有找到其他的東西,那就不得不去做。 – VitalyB