C#COM服务器调用应该在哪里配置资源?

C#COM服务器调用应该在哪里配置资源?,c#,com,com-interop,C#,Com,Com Interop,我用C#实现了一个COM对象(见下文)。它拥有一些IDisposable资源。我应该在哪里处置该资源 似乎从未调用终结器,并且我无法重载IUnknown::Release方法 [ComVisible(true)] [Guid("1992EC2F-087A-4264-B5B2-5E2E757F1A75")] public class ComServer { IDisposable disposableResource; //where to dispose IDisposable reso

我用C#实现了一个COM对象(见下文)。它拥有一些
IDisposable
资源。我应该在哪里处置该资源

似乎从未调用终结器,并且我无法重载
IUnknown::Release
方法

[ComVisible(true)]
[Guid("1992EC2F-087A-4264-B5B2-5E2E757F1A75")]
public class ComServer
{
    IDisposable disposableResource; //where to dispose IDisposable resource?
    public ComServer() 
    {
        disposableResource = File.Open(@"c:\somefile.txt", FileMode.OpenOrCreate); 
        Console.WriteLine("ComServer.ComServer");
    }
    ~ComServer() //finalizer is never called!
    {
        disposableResource.Dispose(); 
        Console.WriteLine("ComServer.~ComServer");
    }
}

已编辑:COM服务器在本机第三方应用程序中使用,无法在客户端调用
Dispose
,也无法在客户端进行任何更改。

如果对象未标记为垃圾收集,则将永远不会调用Finalizer
。去找找原因。 至于
处置
,只有您可以决定何时处置您的对象。这取决于对象的体系结构和生命周期。一般来说,当不再需要对象时,应该调用
Dispose()

您可以做的最好的事情是在
ComServer
上实现
IDisposable
,并在不再需要对象的地方调用
Dispose
,或者您可以使用构造将它们包装在

Tseng提供了一个标准实现的例子:<代码> IDISPOSTABLE 模式,尽管考虑到一个好的程序不需要终结器。通常,让对象依赖于终结机制是一种不好的做法


如果您想测试终结器,但无法创建对象,请不要处理它,请调用
GC.Collect()
。此调用将强制垃圾收集,如果对象符合垃圾收集条件,则将调用终结器。但是请记住,永远不要将
GC.Collect()
用作生产代码的一部分

无法保证何时调用finalize。您的ComServer应该实现IDiposable接口本身,并在其中释放其一次性成员

从(如果您覆盖
对象。完成

如果要定义使用非托管资源和 或者有,或者可能有,应该是 disposed,您应该实现IDisposable.Dispose方法和 提供第二个重载Dispose,如下一节所述 节

然后,如果需要Dispose,请显式调用Dispose,或者尽可能使用
using

using(ComServer com = new ComServer()) {
    // operate on the ComServer
} // Dispose will be called automatically when the leaving the using block

这个问题真的是非此即彼。简短版本:.NET COM包装器在COM对象上保留一个ref计数,因此即使您可以拦截
Release()
,也不会看到ref计数变为零。您的客户端需要显式调用
Dispose()
。请注意,如果您的服务器接口使用
Dispose()
Close()
方法是有意义的,那么您可以将该方法放在那里。否则,您需要让客户机查询
IDisposable
,并从中获取
Dispose()
方法。这在另外两个问题中有更详细的解释。谢谢你的回答!不幸的是,com客户端是本机第三方应用程序,因此插入IDisposable毫无意义
using(ComServer com = new ComServer()) {
    // operate on the ComServer
} // Dispose will be called automatically when the leaving the using block