Добавление COM-оболочки .net в кэш по значению вместо ref - PullRequest
0 голосов
/ 07 января 2010

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

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

Ответы [ 2 ]

0 голосов
/ 07 января 2010

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

Я не сторонник "измерения решить все проблемы производительности", но в вашем случае, вы должны.

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

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

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

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

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

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

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

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

0 голосов
/ 07 января 2010

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

...