从元帅那里获得RCW

发布于 2025-02-10 03:32:33 字数 1538 浏览 2 评论 0 原文

我有一个Excel加载项,需要大量的长期参考来对Excel本机对象。当用户关闭Excel时,时不时地将其“悬挂”保持在背景中。

)信任gc 进行手动清理。从口头上讲,我信任GC,当加载项卸载良好时也可以这样做:

do {
    GC.Collect();
    GC.WaitForPendingFinalizers();
}
while (Marshal.AreComObjectsAvailableForCleanup());

但是现在,这个问题一直在随机弹出,我发现很难弄清楚它可能是什么。还插入了元帅。Releasecomobject到处都是,但时不时地仍然悬挂。

因此,我在想,如果我可以问元帅。arecomobjectsavailableforcleanup,那么显然有一个由 Marshal 保留的RCW的中心列表?

有没有办法进入此列表并显示有关持有本机对象的信息?这对寻找罪犯真的很有帮助。 我查看但似乎没有任何可用的东西。 Looking at the source这条路在此通话中死了:

[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int InternalReleaseComObject(Object o);

但是也许这里有人知道一种继续并列出对象的方法吗?

当然,其他任何建议让Excel正确关闭的建议也非常欢迎。

I have an Excel add-in that needs a lot of long running references to Excel native objects. Every now and then when a user closes Excel it 'hangs' keeping an Excel process live in the background.

There's quite been some debate between trusting the GC and doing manual cleanup. Orignially I trusted the GC, also doing this when the add-in unloads for good measure:

do {
    GC.Collect();
    GC.WaitForPendingFinalizers();
}
while (Marshal.AreComObjectsAvailableForCleanup());

but now the issue keeps popping up at random and I'm finding it hard to figure out what it could be. Also inserted Marshal.ReleaseComObject everywhere but every now and then it still hangs.

So I was thinking, if I can ask Marshal.AreComObjectsAvailableForCleanup then apparently there's a central list of RCW's being kept by Marshal?

Is there a way to get to this list and display information about the native objects being held? That would be really helpful in finding the offender.
I looked over the public methods but there does not seem to be anything available. Looking at the source the trail goes dead at this call:

[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int InternalReleaseComObject(Object o);

But maybe someone here knows a way to continue and list the objects?

Any other suggestions to get Excel to shut down properly also welcome of course.

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

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

发布评论

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

评论(1

椒妓 2025-02-17 03:32:33

我遇到了类似的问题,即关闭后Excel崩溃,对我来说,这也与COM对象未正确发布时有关。

I have followed Goverts suggestion to use the OnDisconnection (here using the Ribbon deriving from ExcelComAddIn which implents IDTExtensibility2) method (Functions.StatusCollection and DBModifDefColl are collections of dynamically allocated objects containing references to excel ranges, which are then explicitly released using Marshal.ReleaseComObject) :

Public Class MenuHandler
  Inherits CustomUI.ExcelRibbon

  Public Overrides Sub OnDisconnection(RemoveMode As ExcelDna.Integration.Extensibility.ext_DisconnectMode, ByRef custom As Array)
    For Each aKey As String In Functions.StatusCollection.Keys
        Dim clearRange As Excel.Range = Functions.StatusCollection(aKey).formulaRange
        If Not IsNothing(clearRange) Then Marshal.ReleaseComObject(clearRange)
    Next
    For Each DBmodifType As String In DBModifDefColl.Keys
        For Each dbmapdefkey As String In DBModifDefColl(DBmodifType).Keys
            Dim clearRange As Excel.Range = DBModifDefColl(DBmodifType).Item(dbmapdefkey).getTargetRange()
            If Not IsNothing(clearRange) Then Marshal.ReleaseComObject(clearRange)
        Next
    Next
    Do
        GC.Collect()
        GC.WaitForPendingFinalizers()
    Loop While (Marshal.AreComObjectsAvailableForCleanup())
  End Sub
...

一旦实现了这一目标,我将不再发生Excel关闭的崩溃...

I had a similar problem with Excel crashing after being closed and for me it was also related to COM Objects not being released properly on shutdown.

I have followed Goverts suggestion to use the OnDisconnection (here using the Ribbon deriving from ExcelComAddIn which implents IDTExtensibility2) method (Functions.StatusCollection and DBModifDefColl are collections of dynamically allocated objects containing references to excel ranges, which are then explicitly released using Marshal.ReleaseComObject):

Public Class MenuHandler
  Inherits CustomUI.ExcelRibbon

  Public Overrides Sub OnDisconnection(RemoveMode As ExcelDna.Integration.Extensibility.ext_DisconnectMode, ByRef custom As Array)
    For Each aKey As String In Functions.StatusCollection.Keys
        Dim clearRange As Excel.Range = Functions.StatusCollection(aKey).formulaRange
        If Not IsNothing(clearRange) Then Marshal.ReleaseComObject(clearRange)
    Next
    For Each DBmodifType As String In DBModifDefColl.Keys
        For Each dbmapdefkey As String In DBModifDefColl(DBmodifType).Keys
            Dim clearRange As Excel.Range = DBModifDefColl(DBmodifType).Item(dbmapdefkey).getTargetRange()
            If Not IsNothing(clearRange) Then Marshal.ReleaseComObject(clearRange)
        Next
    Next
    Do
        GC.Collect()
        GC.WaitForPendingFinalizers()
    Loop While (Marshal.AreComObjectsAvailableForCleanup())
  End Sub
...

Once this was implemented I had no more crashes on excel shutdown...

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