Что вызывает InvalidComObjectException: «COM-объект, который был отделен от его основного RCW, не может быть использован»?

Я рассмотрел различные вопросы, в которых упоминается это конкретное исключение ( в этом вопросе перечислены многие из них , которые я побывал). Кроме того, у меня такой же общий вопрос, что и в этом сообщении , но в другом контексте, поэтому ответ мне не поможет.

Контекст

У меня есть класс, производный от AxWindowsMediaPlayer , который принадлежит классу с именем View , который находится на панели , в рабочем пространстве . Я недавно задал вопрос об этой ситуации, но этот вопрос был направлен на то, подходит ли мой способ решения этой проблемы. Предыстория этого вопроса актуальна здесь:

    .-----------------------.
    |Workspace              |
    |.--------.  .--------. |
    ||Panel1  |  |Panel2  | |
    ||.-----. |  |.-----. | |
    |||View1| |  ||View2| | |
    ||'-----' |  |'-----' | |
    |'--------'  '--------' |
    '-----------------------'

Когда View удаляется, для всех оставшихся View вызывается метод Synchronize () . ] объекты. Для представления , содержащего AxWindowsMediaPlayer , оно вызывает videoPlayer.Error.clearErrorQueue () .

Проблема

Когда я вызываю Dispose () на верхнем уровне ( Workspace.Dispose () ), если другое представление удаляется и затем вызывает Synchronize () для оставшихся объектов View , то представление , содержащее ] Класс AxWindowsMediaPlayer вызывает исключение в строке videoPlayer.Error.clearErrorQueue () , заявляя:

InvalidComObjectException: COM-объект, который был отделен от лежащего в его основе RCW, не может использоваться.

Я озадачен тем, как AxWindowsMediaPlayer отделяется от лежащего в его основе RCW ( Runtime Callable Wrapper ). Я прочитал эту статью, в которой говорится об этом исключении и об опасностях вызова Marshal.ReleaseComObject () . Я не вызываю этот метод явно. Я установил точки останова в методах Dispose в Panel и View и VideoPlayerControl (происходит от классов AxWindowsMediaPlayer ) , но ни один из них не сработает до того, как произойдет исключение.

Мое решение - убедиться, что View с медиаплеером всегда удаляется первым. Это было мотивацией моего предыдущего вопроса. Но я хотел бы понять, как это происходит, чтобы понять, нужно ли это исправить. Кто вызывает отделение AxWindowsMediaPlayer от его RCW до того, как Dispose будет вызван в родительском классе?

Я предполагаю, что AxWindowsMediaPlayer финализатор вызывается сборщиком мусора, но я не понимаю, что его вызывает. По какой-то причине вызов Dispose на более высоком уровне вызывает вызов Marshal.ReleaseComObject из-под пола. Может кто-нибудь просветить меня?

5
задан Community 23 May 2017 в 12:16
поделиться