Имя: Пароль:
1C
1С v8
Размышления и теория - как хранить COM-объект &НаСервере после выполнения процедур
,
0 Caber
 
31.01.22
07:59
Все переменные &НаСервере и данные этих процедур очищаются после того, как они будут выполнены. С этим мы смирились.
Но COM-объект, это не совсем внутренняя часть инфрастуктуры 1С, поэтому, возможно, есть лазейка.
Дело в том, что мне приходится работать с COM-объектом, который, к сожалению, невозможно использовать в процедурах &НаКлиенте. Возникла проблема - при каждом действии приходится создавать объект, что занимает много времени (несколько секунд). Я задумался - что можно придумать, чтобы COM-объект висел созданным каким либо образом. Есть мысли или опыт реализации такого костыля?
1 Ryzeman
 
31.01.22
08:09
Насколько я понимаю то, что ты хочешь сделать нельзя, так как ни во временное хранилище COM-объекты не кладутся ни с клиента на сервер и назад не передаются.
Вопрос - а зачем в принципе во время работы с com-объектом бегать на клиент постоянно? Нельзя ли переписать логику так, что бы опросить изменения на клиенте сразу и внести нужные изменения в объект? Вариант - сериализовать объект в допустимую для 1с сущность, и после изменений её на клиенте один раз записать на сервере.
2 Мультук
 
гуру
31.01.22
08:12
(0)


&НаСервере
Функция УстановитьСоединение_Бухгалтерия(Соединить = Ложь)
    пСтр = неопределено;
    Если не пустаяСтрока(Объект.АдресВХранилище) Тогда
        пСтр = ПолучитьИзВременногоХранилища(Объект.АдресВХранилище);
    КонецЕсли;        
    
    Если (пСтр = неопределено) или Соединить Тогда
        Парам = СтрокаСоединения_Бухгалтерия();
        V83COMConnector= Новый COMОбъект("V83.COMConnector");
        Попытка
            соед = V83COMConnector.Connect(Парам);
            
            пСтр = Новый Структура("COMОбъект", соед);
            Объект.АдресВХранилище = ПоместитьВоВременноеХранилище(пСтр, ЭтаФорма.УникальныйИдентификатор);
        Исключение
            Сообщить("Ошибка подключения к внешней системе !" + ОписаниеОшибки());
        КонецПопытки;
        
    Иначе
        соед = пСтр.COMОбъект;
    КонецЕсли;
    
    Возврат соед;
КонецФункции
3 Chai Nic
 
31.01.22
08:15
Тема существует столько же, сколько и управляемое приложение.

Способов фактически два.

1. Возвращать внешний объект из общего модуля с галкой повторного возвращения значений
2. Сериализовать его в составе структуры и хранить в параметрах сеанса

Оба способа натыкаются на проблемы.

а. Время хранения кэшированных значений не более 20 минут, а если платформа считает что памяти мало - то и того меньше
б. Объекты, на которые 1с "не видит" ссылку в явном виде (а сериализованную она не видит) считаются мусором и могут удалиться в любое время.
в. Объект существует в контексте рабочего процесса в случае клиент-сервера. А рабочих процессов мало того что может быть несколько, так они могут быть ещё и на нескольких серверах.

Так что, по обоим вариантам нужно проверять перед использованием, является ли то, что получено, именно COM-объектом и живой ли он. Ну и периодически есть риск, что получить не удалось и придется заново инициализировать объект, с соответствующими задержками...
4 Гений 1С
 
гуру
31.01.22
08:16
(0) сделай отдельный процесс на сервере, который крутит бесконечный цикл и обрабатывает очередь (например через регламентное задание)
помещай в РС очереди заявки, а процесс будет их отрабатывать и помещать результат.
Тогда COM на сервере может жить вечно.
Ну, единственно надо прописать логику запуска службы, если она отвалилась.
5 Chai Nic
 
31.01.22
08:18
(4) Вариант, но имеет недостаток в виде кванта времени. То есть, мгновенной реакции не получится.
6 Caber
 
31.01.22
08:38
(3) > Возвращать внешний объект из общего модуля с галкой повторного возвращения значений
   - Это что получается, COMОбъект, созданный в таком модуле, и вправду не уничтожается после завершения процедуры? интересно...
> Сериализовать его в составе структуры и хранить в параметрах сеанса
   - Я тут не до конца понимаю, как это физически работает. Сериализация, насколько я понимаю, это представление какого либо физического объекта в виде снимка, что то вроде дампа оперативной памяти. Так как com-объект это вполне себе работающий процесс, то может быть его и можно сериализовать, то вот обратно - нет. Или я не так понимаю эту архитектуру.
(4) хитро. Учитывая, что есть способы бесконечного цикла без загрузки ЦП, то вполне себе рабочий вариант.
7 acht
 
31.01.22
08:39
(0) > Но COM-объект, это не совсем внутренняя часть инфрастуктуры 1С

А переменная, куда ты кладешь COM-объект - это вот гарантировано внутренняя часть инфрастуктуры 1С.
8 Chai Nic
 
31.01.22
08:39
(6) Сериализация в 1с - это превращение объекта в строку. Параметры сеанса и объекты временного хранилища хранятся именно как строки. При сериализации COM-объекта по сути происходит сериализация ссылки на него.
9 Chai Nic
 
31.01.22
08:42
+(8) И про "десериализации" мы получаем некую ссылку, а вот что там за этой ссылкой - хрен знает. Если нам повезло и мы попали на тот же рабочий процесс, а объект не был вычищен сборщиком мусора - то ура. Иначе увы.
10 Megas
 
31.01.22
08:43
(3) Дольше =)
Я таким вопросом задавлся ещё году в 2008, что бы com жил на сервере а к нему обращались с клиента.
Единственное что пришло в голову это что Гений описал в (4). И не реализовал так как отклик будет долгий и много писанины.
2 + 2 = 3.9999999999999999999999999999999...