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?