Winforms 是什么导致InvalidComObjectException:“;无法使用已与其基础RCW分离的COM对象;?
我已经看了各种各样的问题,其中提到了这个特殊的例外(我已经访问过)。另外,我有相同的,但在不同的背景下,所以对我没有帮助 上下文 我有一个派生自的类,它属于一个名为Winforms 是什么导致InvalidComObjectException:“;无法使用已与其基础RCW分离的COM对象;?,winforms,interop,activex,dispose,finalizer,Winforms,Interop,Activex,Dispose,Finalizer,我已经看了各种各样的问题,其中提到了这个特殊的例外(我已经访问过)。另外,我有相同的,但在不同的背景下,所以对我没有帮助 上下文 我有一个派生自的类,它属于一个名为视图的类,它位于面板中的工作区中。我最近问了这个问题,但那个问题是针对我解决这个问题的方法是否可行。该问题的背景与此相关: .-----------------------. |Workspace | |.--------. .--------. | ||Panel1 | |Pa
视图
的类,它位于面板
中的工作区
中。我最近问了这个问题,但那个问题是针对我解决这个问题的方法是否可行。该问题的背景与此相关:
.-----------------------.
|Workspace |
|.--------. .--------. |
||Panel1 | |Panel2 | |
||.-----. | |.-----. | |
|||View1| | ||View2| | |
||'-----' | |'-----' | |
|'--------' '--------' |
'-----------------------'
.-----------------------.
|工作空间|
|.--------. .--------. |
||面板1 | |面板2 ||
||.-----. | |.-----. | |
|||视图1 | | | |视图2 | ||
||'-----' | |'-----' | |
|'--------' '--------' |
'-----------------------'
当一个视图
被释放时,一个名为Synchronize()
的方法将在所有剩余的视图
对象上被调用。对于包含AxWindowsMediaPlayer的视图
,它调用
问题
当我在顶层调用Dispose()
(Workspace.Dispose()
)时,如果另一个视图
被释放,然后导致对剩余的视图
对象调用Synchronize()
,包含AxWindowsMediaPlayer类的视图
在videoPlayer.Error.clearErrorQueue()
行引发异常,声明:
InvalidComObjectException:无法使用已与其基础RCW分离的COM对象
我对AxWindowsMediaPlayer
如何与其底层RCW()分离感到困惑。我读过关于打电话的危险的书。我没有显式地调用这个方法。我在面板
和视图
和视频播放控制
(源自AxWindowsMediaPlayer
)类的Dispose
方法中设置了断点,但在异常发生之前,这些方法都不会被命中
我的解决方法是确保始终首先处理带有媒体播放器的视图。这就是我上一个问题背后的动机。但我想了解这是如何发生的,这样我就能知道这是否是我需要解决的问题在父类上调用Dispose
之前,是谁导致AxWindowsMediaPlayer
与其RCW分离的?
我的猜测是,AxWindowsMediaPlayer
终结器正在被GC调用,但我不知道是什么触发了它。出于某种原因,在更高级别调用Dispose
会导致在地板下调用封送.ReleaseComObject
。有人能给我点化一下吗?不幸的是,您的解决办法就是
Control.Dispose
首先递归地处理所有ActiveX控件,然后对子控件递归调用Dispose
。在您的示例中,如果调用Workspace.Dispose
,将首先处理您的AxWindowsMediaPlayer
,然后处理Panel1
、Panel2
、View1
、View2
(取决于您构建控件树的顺序)
我们可以通过使用来发现原因。如果我们检查Control.Dispose
,它基本上是按如下方式实现的(注意,忽略了不相关的代码,并对其进行了轻微更改以提高可读性):
而disposeAxControl
的实现方式如下:
internal virtual void DisposeAxControls()
{
foreach (Control control in Controls)
{
control.DisposeAxControls();
}
}
AxHost
类重写disposeAxControl
以销毁托管ActiveX控件
我不太清楚为什么存在dispeaxcontrols
函数。似乎像其他人一样,AxHost
会简单地覆盖Dispose
,以销毁ActiveX控件,但实际情况并非如此
internal virtual void DisposeAxControls()
{
foreach (Control control in Controls)
{
control.DisposeAxControls();
}
}