一段时间以来,我在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