我在管理COM对象方面不是非常方便。我已经做了相当多的阅读,但是我无法完全理解当你有两个引用指向单个COM对象时会发生什么,并释放其中一个。考虑以下[半]假设:
我在C#中为Excel工作簿创建了一个基本的包装类:
using ExcelInterop = Microsoft.Office.Interop.Excel;
...
public class WorkbookWrapper : IDisposable
{
protected internal ExcelInterop.Workbook _wb;
public WorkbookWrapper(ExcelInterop.Workbook workbook)
{
_wb = workbook;
}
public WorkbookWrapper(WorkbookWrapper workbookWrapper)
{
_wb = workbookWrapper._wb;
}
#region IDisposable
// basic Dispose function which releases _wb COM Object (omitted to shorten post length)
#endregion
...
}
对于我正在处理的一个特定项目,我发现有必要在WorkbookWrapper
个对象上附加一些额外的信息,所以我扩展了它:
class LinkingWorkbookWrapper : WorkbookWrapper
{
internal string workbookGUID = null;
internal LinkingWorkbookWrapper(WorkbookWrapper workbookWrapper, string GUID) : base(workbook)
{
workbookGUID = GUID;
}
...
}
这个特殊的类使用WorkbookWrapper(WorkbookWrapper)
构造函数来存储对Interop Workbook的新引用,这在使用如下函数时突然出现问题:
public static void ProcessAllCharts(WorkbookWrapper wbw)
{
LinkingWorkbookWrapper lwbw = null;
if(wbw is LinkingWorkbookWrapper)
lwbw = (LinkingWorkbookWrapper)wbw;
else
lwbw = new LinkingWorkbookWrapper(wbw, GenerateGUID());
//... do stuff ...
}
现在让我们说函数必须接受正常的WorkbookWrapper
。 何时是处理lwbw
的适当时间? 如果我在ProcessAllCharts
结尾处这样做,我可能会分开引用的COM对象来自RCW的原始wbw
;另一方面,如果我不处理lwbw
,我冒着将对象的引用留在以太中的风险。
答案 0 :(得分:0)
这个人真的属于Hans Passant,他随意地删除了原始问题的评论,但从未发布实际答案。
在lengthy answer to another question中,他详细说明了手动释放的原因至多是傻瓜的差事。他还详细介绍了为什么我们实际上会让这些鬼实体徘徊,以及如何摆脱它们。我真的鼓励任何有这个问题的人去阅读整个帖子(这是非常有用的信息),但是如果你现在处于困境并需要,那么让我总结一下:
是的,就是这样。这里的所有都是它的。调试器有点唠叨,似乎说服垃圾收集器,当它们真的没有时,有些东西仍然很重要。我知道,你不认为这是你的问题,你认为这是疯狂的。我也有同感,但试一试;快速解决我的问题。
再次感谢Hans Passant,你坚忍C-Sharpian。