分别释放对COM对象的多个引用

时间:2014-10-14 14:53:57

标签: c# dispose comobject

我在管理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,我冒着将对象的引用留在以太中的风险。

1 个答案:

答案 0 :(得分:0)

这个人真的属于Hans Passant,他随意地删除了原始问题的评论,但从未发布实际答案。

lengthy answer to another question中,他详细说明了手动释放的原因至多是傻瓜的差事。他还详细介绍了为什么我们实际上会让这些鬼实体徘徊,以及如何摆脱它们。我真的鼓励任何有这个问题的人去阅读整个帖子(这是非常有用的信息),但是如果你现在处于困境并需要,那么让我总结一下:

enter image description here

是的,就是这样。这里的所有都是它的。调试器有点唠叨,似乎说服垃圾收集器,当它们真的没有时,有些东西仍然很重要。我知道,你不认为这是你的问题,你认为这是疯狂的。我也有同感,但试一试;快速解决我的问题。

再次感谢Hans Passant,你坚忍C-Sharpian。