Добавление оболочки .net COM для кэширования по значению, а не по ссылке

StackOverflow https://stackoverflow.com/questions/2019670

Вопрос

В своем коде я создаю экземпляр устаревшего объекта Delphi через COM-интерфейс.Этот класс необходимо создавать много раз, поэтому, чтобы снизить затраты на его создание, я кэширую его в точке, где 70% всех вызовов имеют общий результирующий объект.

Однако когда я изменяю объект после его кэширования, изменения также сохраняются в кеше.Это заставляет меня думать, что экземпляр оболочки COM передается по ссылке, а не по значению.
Как я могу убедиться, что объект в кеше передается по значению, а не по ссылке?

Это было полезно?

Решение

Я думаю, что если это вообще возможно, вам нужно явно клонировать копию объекта, а затем кэшировать эту копию.См., например, MemberwiseClone метод и другие, упомянутые в ответах на Клонирование объектов в C#.

Другие советы

Во-первых, нужно ли это?

Я не сторонник того, чтобы «измерение решает все проблемы с производительностью», но в вашем случае вам следует это сделать.

Накладные расходы на создание экземпляра COM-объекта (после штрафа за первый вызов) как таковые очень малы — помните, что 15 лет назад он был разработан для того, чтобы обеспечить возможность использования множества небольших объектов на компьютерах.Я предполагаю, что накладные расходы .NET не намного больше, поэтому вопрос заключается в собственной инициализации объектов.

Вы можете легко это проверить, создав экземпляры 1000 объектов в тесном цикле (отбросьте первый вызов, это может быть очень дорого и испортит среднее значение).

COM-объекты по своей сути создаются по ссылке.
Для COM-объектов не существует «передачи по значению», поскольку их базовый интерфейс представляет собой указатель на экземпляр с подсчетом ссылок, а COM не предоставляет общий метод «Клонировать».

возможное решение:Копирование при записи
Если только если создание экземпляра Действительно дорого, а большинство вызовов можно выполнить через экземпляр по умолчанию, вы можете реализовать схему копирования при записи.

Вам необходимо создать класс-оболочку, содержащую ссылку на экземпляр по умолчанию и ссылку на частный экземпляр, инициализированный значением 0.

Пока частный экземпляр null, все функции получения пересылаются в экземпляр по умолчанию, в противном случае они пересылаются в частный экземпляр.

Каждый вызов установщика/мутатора перенаправляется к частному экземпляру, создавая его, когда он не существует.

Это задержит создание частного экземпляра до первого мутирующего вызова.Однако вам придется обернуть все интересующие интерфейсы для этого компонента.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top