【问题标题】:Should I treat objects from a "dumb" managed wrapper over a native COM dll as unmanaged resources?我应该将原生 COM dll 上的“哑”托管包装器中的对象视为非托管资源吗?
【发布时间】:2012-01-26 01:41:55
【问题描述】:

我的托管应用程序使用本机 COM dll 通过托管包装器公开的遗留功能。我无法更改 COM dll 及其托管包装器。

  • 托管包装器本质上是由脚本自动生成的,将 COM 类型声明作为输入。
  • COM 层将在内部访问网络、文件系统、图形和其他非托管资源。
  • 包装器中的大多数托管类型都是使用类似工厂的方法创建的。
  • 包装器中的大多数托管类型无法手动触发清理或资源释放。
  • 包装器中没有托管类型实现 IDisposable。
  • 包装器中没有托管类型显式实现终结器。

我觉得我希望看到这个 API 在我的应用程序层中遗漏了很多东西,以确保正确释放非托管资源。

问题是我对此的理解是否正确:

鉴于应用程序层不再引用托管包装器中的对象,因此无法释放该托管对象使用的底层本机对象直到公开的清理方法明确这样做

我说的对吗?

【问题讨论】:

  • 您在询问 Marshal.ReleaseComObject()。当您在搜索框中键入它时,它会被大量点击。不,除非 COM 对象接口非常简单,否则使用它不是一个好主意。把它留给垃圾收集器来确保它始终正确。 GC.Collect() 如果你有内存问题。
  • @Hans:很好的答案。将其从评论中更改为,并获得当之无愧的信誉。 ;-)
  • @Hans:实际上,Marshal.ReleaseComObject()并没有暴露在 Silverlight 中。 :-(
  • 是的,这并不令人惊讶。嗯,很好,那你就不用担心了:)

标签: c# silverlight com resources


【解决方案1】:

不,这不太正确。当垃圾收集器收集引用 COM 类型的托管类型时,将使用 COM Release 调用取消引用这些引用。此时将释放非托管资源,假设没有其他内容引用 COM 对象实例。

但是,除非您调用 GC.Collect()(这是一件相当严厉的事情),否则这些非托管资源可能会被占用的时间远远超过必要的时间。

【讨论】:

  • 啊,我明白了!对 COM 对象 Release() 函数的调用正是我所缺少的。那么 COM 包装器会自动执行此操作吗?多么漂亮!
猜你喜欢
  • 2015-10-28
  • 2011-12-29
  • 2011-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-23
  • 2020-05-03
  • 2011-01-05
相关资源
最近更新 更多