Должен ли управляемый класс, обертывающий интерфейс DirectSound, быть IDisposable? - PullRequest
0 голосов
/ 18 июня 2010

Я пишу управляемую оболочку вокруг DirectSound.(Это простая частичная оболочка, которая решает мою конкретную проблему и не более того. Не говорите мне о NAudio или чем-то подобном.) Должен ли управляемый класс, который упаковывает IDirectSound8, быть IDisposable и почему?Тот же вопрос о IDirectSoundBuffer8.

1 Ответ

1 голос
/ 18 июня 2010

Технически: да.Практически: нет.IDirectSound8 - это интерфейс COM, они очень удобно заключены в .NET с библиотекой взаимодействия.RCW.Это RCW управляет подсчетом ссылок на базовом объекте COM класса.RCW не реализует IDisposable, даже если он очень сильно зависит от неуправляемого ресурса.

Причина этого заключается в том, что практически невозможно правильно реализовать IDisposable.COM-класс COM реализует несколько интерфейсов, создавая один добавляет счетчик ссылок.Вы должны быть на 100% уверены, что все из этих указателей интерфейса больше не используются, прежде чем удаление станет безопасным.Это очень сложно сделать, эти указатели создаются неожиданным образом.Как и при использовании индексированного свойства одного из интерфейсов, указатель промежуточного интерфейса никогда не виден в вашем коде.

Это не является реальной проблемой, сборщик мусора заботится о количестве ссылок, финализатор получает заданиесделанный.Просто для освобождения объекта требуется немного больше времени.Стандартное поведение GC.К сожалению, COM-серверы вне процесса имеют заметные побочные эффекты, программисты, как правило, раздражаются, когда процесс не исчезает из списка процессов TaskMgr в тот момент, когда их код перестает использовать интерфейсы.Многие, многие вопросы «Excel / Word не завершаются» здесь и на форумах.

Если вы все равно хотите это реализовать, вы можете сделать это, вызвав Marshal.FinalReleaseComObject () в вашей реализации Dispose ().,Просто остерегайтесь значительного увеличения риска сбоя, неправильный вызов вызывает очень серьезные проблемы с диагностикой сбоя.Совсем не похоже на удаление объекта в нативном коде и сохранение указателя на него.Если это на самом деле «тяжелый» объект, который должен быть немедленно освобожден, то GC.Collect () + GC.WaitForPendingFinalizers () выполняет свою работу с гораздо меньшим риском ошибиться.С побочными эффектами конечно.

...