I've looked at the various questions that mention this specific exception (this question lists many of them, which I've visited). Also, I have the same general question as this post, but in a different context, so the answer is not helpful to me.
The context
I have a class derived from AxWindowsMediaPlayer
that is owned by a class called View
, which is within a Panel
, within a Workspace
. I recently asked a question around this situation, but that question was directed towards whether my workaround for this problem is okay. The background from that question is relevant here:
.-----------------------. |Workspace | |.--------. .--------. | ||Panel1 | |Panel2 | | ||.-----. | |.-----. | | |||View1| | ||View2| | | ||'-----' | |'-----' | | |'--------' '--------' | '-----------------------'
When a View
gets disposed, a method called Synchronize()
will get called on all of the remaining View
objects. For the View
that contains the AxWindowsMediaPlayer
, it calls videoPlayer.Error.clearErrorQueue()
.
The problem
When I call Dispose()
at the top level (Workspace.Dispose()
), if another View
gets disposed and then causes Synchronize()
to be called on the remaining View
objects, the View
containing the AxWindowsMediaPlayer
class throws an exception on the videoPlayer.Error.clearErrorQueue()
line, stating:
InvalidComObjectException: COM object that has been separated from its underlying RCW cannot be used.
I'm puzzled by how the AxWindowsMediaPlayer
is getting separated from its underlying RCW (Runtime Callable Wrapper). I've read this article that talks about this exception and the dangers of calling Marshal.ReleaseComObject()
. I am not calling this method explicitly. I have put breakpoints at the Dispose
methods of Panel
and View
and VideoPlayerControl
(derives from AxWindowsMediaPlayer
) classes, but none of those get hit before the exception happens.
My workaround is to make sure that the View
with the media player always gets disposed first. This was the motivation behind my previous question. But I'd like to understand how this is happening so I can see whether this is something I need to fix. Who is causing the AxWindowsMediaPlayer
to be separated from its RCW before Dispose
is getting called on the parent class?
My guess is that the AxWindowsMediaPlayer
finalizer is getting called by the GC, but I don't understand what is triggering it. For some reason, calling Dispose
at the higher level is causing Marshal.ReleaseComObject
to get called under the floor. Can someone enlighten me?