Как хранить COM-объект в памяти файловой базы 1С без постоянного пересоздания?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке интеграций в системе 1С:Предприятие часто возникает задача взаимодействия с внешними системами через COM-соединение. Одной из главных проблем является низкая скорость инициализации COM-объекта. Если нам требуется часто обращаться к внешней базе или приложению, постоянное создание объекта через Новый COMОбъект существенно замедляет работу пользователя. Рассмотрим ситуацию, когда база данных является файловой и однопользовательской, и выясним, как можно «заставить» систему помнить объект между вызовами серверных процедур.

Проблема разделения контекста в управляемом приложении

В современных конфигурациях на управляемых формах мы сталкиваемся с жестким разделением кода на клиентский и серверный. В тонком клиенте серверные вызовы происходят в отдельном контексте. Даже если база файловая и физически всё выполняется в одном процессе 1cv8.exe, платформа имитирует поведение клиент-серверного варианта. Проанализируем, почему стандартные механизмы хранения данных не подходят для COM-объектов:

Решение №1: Использование толстого клиента (управляемое приложение)

Разберем наиболее эффективный способ для файлового варианта базы данных. Как выяснилось в ходе обсуждения, использование режима «Толстый клиент (управляемое приложение)» позволяет обойти ограничения разделения контекста. В этом режиме клиентская и серверная части кода работают в одном адресном пространстве без имитации передачи данных через сериализацию.

Выясним, как это реализовать на практике. Нам необходимо объявить переменную в Модуле управляемого приложения с ключевым словом Экспорт. Рассмотрим пример кода:


// В Модуле управляемого приложения
Переменная КэшCOMОбъекта Экспорт;

Процедура ПриНачалеРаботыСистемы()
    // Инициализируем объект при старте, если это необходимо
    // КэшCOMОбъекта = Новый COMОбъект("Excel.Application");
КонецПроцедуры

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

Важно: Чтобы этот метод заработал, в настройках пользователя или в параметрах запуска (в конфигураторе или через строку запуска /RunModeOrdinaryApplication — для обычных, либо соответствующий флаг в настройках запуска для управляемых) должен быть разрешен запуск толстого клиента.

Решение №2: Модули с повторным использованием значений

Если по каким-то причинам переход на толстый клиент невозможен, рассмотрим вариант использования функционала платформы под названием «Повторное использование возвращаемых значений». Для этого создается общий модуль, в свойствах которого устанавливается параметр «Повторное использование» в значение «На время сеанса».

Рассмотрим пример функции в таком модуле:


Функция ПолучитьCOMСоединение() Экспорт
    // Платформа проверит, есть ли результат выполнения этой функции в кэше
    Соединение = Новый COMОбъект("V83.COMConnector");
    // Настройка соединения...
    Возврат Соединение;
КонецФункции

Однако здесь есть подводные камни, которые мы должны учитывать:

  1. Время жизни: Несмотря на настройку «На время сеанса», кэш может быть очищен системой автоматически через 20 минут бездействия или при нехватке оперативной памяти.
  2. Сериализация: В клиент-серверном варианте этот метод не позволит передать COM-объект на клиент, но в файловом варианте, за счет общего процесса, это часто срабатывает, так как физического копирования данных между разными адресными пространствами не происходит.

Решение №3: Внешние компоненты (Native API)

Проанализируем более продвинутый подход. Если COM-объект крайне нестабилен или требует особого контроля жизненного цикла, можно использовать «обертку» в виде Внешней компоненты (ВК). ВК, написанная на C++ или C#, может хранить COM-объект в своей статической памяти.

Для 1С это будет выглядеть как обычный объект внешней компоненты, который при каждом вызове метода просто транслирует команды уже созданному внутри компоненты COM-объекту. Этот метод является наиболее надежным, так как память внешней компоненты не управляется кэшем 1С и объект будет жить ровно столько, сколько открыто само приложение 1С.

Решение №4: Вынос логики во внешний сервис

Рассмотрим ситуацию, когда нам нужна абсолютная независимость. Мы можем создать небольшой HTTP-сервис (например, на Python или Node.js), который будет постоянно держать COM-соединение открытым. 1С в таком случае будет общаться с этим сервисом через HTTPЗапрос.

Посмотрим на преимущества этого подхода:

Выводы и рекомендации

Для файловой однопользовательской базы самым простым и эффективным решением будет использование Толстого клиента и экспортных переменных модуля приложения. Это позволит вам сохранить «реактивность» интерфейса и избежать задержек при каждом обращении к серверу. Если же вы планируете в будущем переходить на серверный вариант, рекомендуем сразу смотреть в сторону модулей с повторным использованием или создания внешней службы, так как логика работы с памятью в клиент-сервере существенно строже.

← На главную