何时使用 ReleaseComObject 与 FinalReleaseComObject?

发布于 2024-09-27 16:10:15 字数 404 浏览 0 评论 0原文

我什么时候应该使用 Marshal.FinalReleaseComObjectMarshal.ReleaseComObject

使用Marshal.FinalReleaseComObject有什么危险吗?

When should I use Marshal.FinalReleaseComObject vs Marshal.ReleaseComObject?

Is there any danger in using Marshal.FinalReleaseComObject?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

独留℉清风醉 2024-10-04 16:10:15

FinalReleaseComObject 有一些优点,它会让你的程序更快地崩溃。 “已与其底层 RCW 分离的 COM 对象无法使用”是 CLR 告诉您您自己处理 COM 引用计数而不是将其保留在 CLR 中是一个错误。您的里程可能会有所不同,您不能真正相信它在您的开发机器上运行时是否正确。确保在将代码部署到客户的计算机时实现良好的错误报告。

优点是代码中只有一个地方出错,即 FinalReleaseComObject 调用。当您使用ReleaseComObject时,它会变得更加模糊。因为这会在一段时间内未被检测到,当 CLR 调用最终的 IUnknown::Release()(即销毁对象的函数)时,程序会崩溃。与错误的 ReleaseComObject 调用相差甚远。但这是世界末日的场景,更有可能的结果是,这个电话没有任何区别,因为你错过了最艰难的时刻。就像 mumble["foo"] 一样,索引器引用很难看到被使用。

嗯,我的建议很明显:不要这样做。您正在与一台永远不会出错的机器竞争。只是这样做有点慢。一个非常好的“来自现实生活的报告”是 可在此处获取。 “沉默的刺客”部分是最相关的。

如果绝对有必要让 COM 服务器立即退出,那么让机器负责将所有引用计数清零。您可以使用 GC.Collect() 来完成此操作。但请记住,如果您希望在调试时也能正常工作,则必须正确放置该调用。它不会以使用 COM 对象的相同方法工作,如此答案中所述。而是将其放在调用方法中。

There's some virtue in FinalReleaseComObject, it will crash your program quicker. "COM object that has been separated from its underlying RCW cannot be used" is the CLR telling you that you taking care of COM reference counts yourself instead of leaving it up the CLR was a mistake. Your mileage may vary, you cannot really trust to get it right when it works on your dev machine. Make sure you implement good error reporting when you deploy the code to your customer's machine.

The virtue is that there's only one place in your code where you got it wrong, the FinalReleaseComObject call. It gets much fuzzier when you use ReleaseComObject. Because that will go undetected for a while, crashing your program when the CLR calls the final IUnknown::Release(), the one that destroys the object. Very far removed from an incorrect ReleaseComObject call. But that's the doomsday scenario, the more likely outcome is that the call just doesn't make any difference because you missed the hard ones. Like mumble["foo"], an indexer reference that is so very hard to see being used.

Well, my advice is obvious: don't do this. You are competing with a machine that never gets it wrong. It is merely a bit slow at doing so. A very good "report from real life" is available here. The "silent assassin" section is most relevant.

If it is absolutely essential to get a COM server to exit instantly then let the machine take care of getting all the reference counts to 0. You do so with GC.Collect(). But do keep in mind that you have to place that call correctly if you want this to also work when you debug. It won't work in the same method that uses the COM objects, explained in this answer. Put it in the calling method instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文