C#COM服务器调用应该在哪里配置资源?
我用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
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