He examinado las diversas preguntas que mencionan esta excepción específica (this question lists many of them, que he visitado). Además, tengo el mismo general question as this post, pero en un contexto diferente, por lo que the answer no es útil para mí.¿Qué causa la excepción InvalidComObjectException: "No se puede usar el objeto COM que se ha separado de su RCW subyacente"?
El contexto
tengo una clase derivada de AxWindowsMediaPlayer
que es propiedad de una clase llamada View
, que está dentro de un Panel
, dentro de un Workspace
. Hace poco pregunté a question acerca de esta situación, pero esa pregunta se dirigió a si mi solución para este problema está bien. El fondo de esta cuestión es relevante aquí:
.-----------------------. |Workspace | |.--------. .--------. | ||Panel1 | |Panel2 | | ||.-----. | |.-----. | | |||View1| | ||View2| | | ||'-----' | |'-----' | | |'--------' '--------' | '-----------------------'
Cuando un View
consigue dispuestos, un método llamado Synchronize()
se llamará en todos los View
objetos restantes. Para el View
que contiene el AxWindowsMediaPlayer
, llama al videoPlayer.Error.clearErrorQueue()
.
El problema
Cuando llamo Dispose()
en el nivel superior (Workspace.Dispose()
), si otro View
consigue dispuestos y luego causas Synchronize()
para ser llamado en los View
objetos restantes, el View
que contiene la clase AxWindowsMediaPlayer
lanza una excepción en la línea de videoPlayer.Error.clearErrorQueue()
, declarando:
InvalidComObjectException: objeto COM que se ha separado de su RCW subyacente no puede b e usado.
estoy desconcertado por la forma en la AxWindowsMediaPlayer
está siendo separado de su RCW subyacente (Runtime Callable Wrapper). He leído this article that talks about this exception y los peligros de llamar al Marshal.ReleaseComObject()
. No estoy llamando a este método explícitamente. He puesto puntos de interrupción en los métodos Dispose
de Panel
y View
y VideoPlayerControl
(deriva de AxWindowsMediaPlayer
) clases, pero ninguno de estos se activan antes de que ocurra la excepción.
Mi solución consiste en asegurarme de que el View
con el reproductor multimedia siempre se elimine primero. Esta fue la motivación detrás de mi pregunta anterior. Pero me gustaría entender cómo está sucediendo esto, así puedo ver si esto es algo que necesito solucionar. ¿Quién está causando que el AxWindowsMediaPlayer
se separe de su RCW antes de llamar al Dispose
en la clase principal?
Supongo que el finalizador AxWindowsMediaPlayer
está siendo llamado por el GC, pero no entiendo qué lo está desencadenando. Por alguna razón, al llamar al Dispose
en el nivel superior está causando que Marshal.ReleaseComObject
se llame bajo el piso. ¿Alguien me puede iluminar?