Я рассмотрел различные вопросы, в которых упоминается это конкретное исключение (в этом вопросе перечислены многие из них, которые я посетил). Кроме того, у меня такой же общий вопрос, как в этом сообщении, но в другом контексте, поэтому ответ мне не поможет.
Контекст
У меня есть класс, производный от AxWindowsMediaPlayer
который принадлежит классу с именем View
, который находится внутри Panel
, внутри Workspace
. Недавно я спросил вопрос об этой ситуации, но этот вопрос был направлен на то, подходит ли мой способ решения этой проблемы. Предыстория этого вопроса актуальна здесь:
.-----------------------. |Workspace | |.--------. .--------. | ||Panel1 | |Panel2 | | ||.-----. | |.-----. | | |||View1| | ||View2| | | ||'-----' | |'-----' | | |'--------' '--------' | '-----------------------'
Когда View
будет удален, для всех оставшихся View
объектов будет вызван метод с именем Synchronize()
. Для View
, содержащего AxWindowsMediaPlayer
, он вызывает videoPlayer.Error.clearErrorQueue()
.
Проблема
Когда я вызываю Dispose()
на верхнем уровне (Workspace.Dispose()
), если другой View
удаляется и затем вызывает вызов Synchronize()
для оставшихся View
объектов, View
, содержащий класс AxWindowsMediaPlayer
, генерирует исключение в строке videoPlayer.Error.clearErrorQueue()
, заявляя:
InvalidComObjectException: COM-объект, который был отделен от основного RCW, использовать нельзя.
Я озадачен тем, как AxWindowsMediaPlayer
отделяется от своего основного RCW (Runtime Callable Wrapper). Я прочитал эта статья, в которой рассказывается об этом исключении и об опасностях вызова _ 20_. Я не вызываю этот метод явно. Я установил точки останова в Dispose
методах классов Panel
, View
и VideoPlayerControl
(производных от AxWindowsMediaPlayer
), но ни один из них не сработает до того, как произойдет исключение.
Мое решение - убедиться, что View
с медиаплеером всегда удаляется первым. Это была мотивация моего предыдущего вопроса. Но я хотел бы понять, как это происходит, чтобы понять, нужно ли это исправить. Кто вызывает отделение AxWindowsMediaPlayer
от его RCW до того, как Dispose
будет вызван в родительском классе?
Я предполагаю, что сборщик мусора вызывает финализатор AxWindowsMediaPlayer
, но я не понимаю, что его запускает. По какой-то причине вызов Dispose
на более высоком уровне вызывает вызов Marshal.ReleaseComObject
из-под пола. Может кто меня просветить?