Моя программа на C # использует компонент COM, который имеет множество различных интерфейсов и подобъектов. Проблема в том, что каждый раз, когда я извлекаю какой-либо COM-интерфейс, создается RCW, и этот RCW существует в течение неизвестного времени (пока не будет собран GC). Каждый RCW содержит некоторый объект на COM-сервере.
Компонент COM является внепроцессным сервером, поэтому его объекты находятся в отдельном довольно тяжелом процессе, который не завершится до тех пор, пока не будут освобождены все находящиеся в нем объекты. Я хочу, чтобы все объекты были выпущены как можно скорее, чтобы я был уверен, что после того, как я выпустил последний объект, процесс внепроцессного сервера завершится и больше не потребляет системные ресурсы. Это не моя паранойя - наличие нескольких тяжелых процессов, потребляющих системные ресурсы, особенно память, действительно плохо сказывается на производительности.
Пока что я создал общий класс, который реализует IDisposable
, принимает ссылку на объект (фактически, RCW) и вызывает _ 2_ в 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
операторов пятиуровневого уровня.
Есть ли более элегантное решение проблемы?