0

我不太擅长管理 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)构造函数来存储对互操作工作簿的新引用,这在使用如下函数时突然出现问题:

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的 s。 什么时候处理合适lwbw 如果我在结尾处这样做,ProcessAllCharts我可能会将原始中引用的 COM 对象wbw与其 RCW 分开;另一方面,如果我不处理lwbw,我会冒着将 COM 对象的引用留在以太中的风险。

4

1 回答 1

0

这个真的属于汉斯帕桑特,他随便放弃了原始问题的评论,但从未发布过实际答案。

对另一个问题的冗长回答中,他详细说明了为什么手动释放充其量只是一件傻事。他还详细介绍了为什么我们实际上会让这些幽灵实例四处游荡,以及如何摆脱它们。我真的鼓励任何有这个问题的人去阅读整篇文章(它非常有用)但是如果你现在处于紧要关头并且需要,让我总结一下:

在此处输入图像描述

是的,就是这样。这里的所有都是它的。调试器有点烦人,似乎喜欢让垃圾收集器相信有些事情在实际上并不重要时仍然很重要。我知道,你不认为这是你的问题,你认为这是疯狂。我也有同样的感觉,但试一试;一下子解决了我的问题。

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

于 2014-10-31T22:11:29.570 回答