Моя программа на C # использует COM-компонент, который имеет множество различных интерфейсов и подобъектов.Проблема заключается в том, что каждый раз, когда я получаю какой-либо COM-интерфейс, создается RCW и этот RCW существует в течение неизвестного времени (пока не будет собран GC).Каждый RCW содержит некоторый объект на COM-сервере.
COM-компонент является сервером out-proc, поэтому его объекты находятся в отдельном довольно тяжелом процессе, который не завершится, пока все объекты, находящиеся в нем, не будутвышел.Я хочу, чтобы все объекты выпускались как можно скорее, чтобы я точно знал, что после того, как я выпустил последний объект, процесс сервера out-proc завершается и больше не потребляет системные ресурсы.Это не моя паранойя - наличие нескольких тяжеловесных процессов, потребляющих системные ресурсы, особенно память, действительно сказывается на производительности.
До сих пор я создавал универсальный класс, который реализует IDisposable
, принимает ссылку на объект (RCW вфакт) и вызывает Marshal.FinalReleaseComObject
в Dispose
реализации.
Ради этого вопроса давайте временно проигнорируем возможные проблемы, возникающие при использовании FinalReleaseComObject()
- я знаю о них иЯ могу терпеть их.
Реальная проблема в том, что я вынужден либо использовать using
для всех объектов, либо писать finally
предложения и вызывать Dispose()
там.Это работает, но код становится довольно загроможденным из-за большого количества дополнительной проводки, и это беспокоит меня.
Например, мне нужно присвоить строку свойству someObject.Params.ColorParams.Hint
- я не могу просто написать
someObject.Params.ColorParams.Hint = whatever;
потому что для каждого средства доступа будет COM-объект, который мне нужно освободить, поэтому вместо этого у меня есть:
using( MyWrapper<IParams> params = new MyWrapper<IParams>( someObject.Params ) ) {
using( MyWrapper<IColorParams> colorParams =
new MyWrapper<IColorParams>( params.Controlled ) )
{
colorParams.Controlled.Hint = whatever;
}
}
, и это самый тривиальный пример - иногда мне нужно получить доступчто-то глубиной в пять уровней, а затем я пишу набор using
операторов глубиной в пять уровней.
Есть ли более элегантное решение проблемы?