Что делать, если COM-соединение вылетает?

Опубликовал Андрей Медведев (1cspbru) в раздел Обмен - Перенос данных из 1C8 в 1C8

Как-то я столкнулся с тем, что соединение с V82.COMConnector вылетало при множественных обращениях ко внешним информационным базам. В статье рассказывается, как побороть недуг. Способ смешной, откровенно говоря. А если проводить медицинские аналогии - чисто хирургический. Надеюсь, что кому-то эта небольшая статья сэкономит время.

Что делать, если COM-соединение вылетает?

Для COM-соединения используется два 1С-объекта: V82.Application, V82.COMConnector. Считается, что объект: V82.Application менее эффективен, так как использует интерфейсные библиотеки, при этом объект V82.COMConnector не имеет в своем арсенале ничего из того, что отвечает за интерфейс.  Казалось бы всё просто и понятно, но есть одно “НО” – при использовании V82.COMConnector   1С 8.2  теряет ключ защиты или вылетает по Run-time (хотя и не всегда, а при некоторых, одному одинэсу ведомых условиях…).

С обозначенной бедой в полной мере я столкнулся в релизе платформы 8.2.15.319 (хотя, в более ранних релизах беда тоже была).  Выглядело это примерно так – при множественных обращениях к информационным базам обработка, которая использовала данные внешних ИБ успешно отрабатывала, а вот при закрытии этой обработки начиналась та самая чехарда. Иногда и не закрывая обработки, а просто попытавшись открыть, скажем, справочник Контрагенты, текущая информационная база радостно вылетала.

Понятно, что первое, что приходит на ум – некорректное закрытие подключений. Но нет, подключение существовало ровно, пока было необходимо. Потом ему присваивалось значение Неопределено. Много еще где копал, но, как выяснилось – искал черную кошку в темной комнате. В конце концов нашел  описание ошибки, зарегистрированное на http://users.v8.1c.ru/ там, где платформы скачивают. В релизе 8.2.15.319 ошибка, как следовало из описания, была исправлена. Однако, моя платформа об этом не знала…

Что в результате? В результате отказался от использования объекта V82.COMConnector и вместо него взял V82.Application и COM-соединение стало работать стабильно. Из негатива только такой нюанс: при отключении внешнего соединения, выдавалось окно диалога, с просьбой подтвердить выход из приложения. Окно мне было без надобности, поэтому отключил его вывод на уровне системной записи, под которой происходило подключение к информационной базе.

 

Такая вот история…

 

Ниже привожу код для подключения с использованием V82.Application.

Модуль формы обработки.

Перем мТекущееПодключение Экспорт ;
…
Процедура ПодключитьИБСерверныйВариант(ИмяСервера, ИмяБазы,  Пользователь, Пароль)   Экспорт           
     мТекущееПодключение = новый COMОбъект("V82.Application");
     Состояние(ИмяБазы + "..." + " возможны интерфейсные сообщения...");
     Connection = Истина;                                                                                  
     Попытка
         Connection = мТекущееПодключение.Connect("Srvr="+СокрЛП(ИмяСервера) + ";" + "Ref="+СокрЛП(ИмяБазы) + ";" + "Usr="+СокрЛП(Пользователь) + ";" + "Pwd="+СокрЛП(Пароль));
     Исключение
         мТекущееПодключение = Неопределено;
         Предупреждение("Ошибка открытия информационной базы" + ИмяБазы );
         Сообщить(ОписаниеОшибки());
     КонецПопытки;
КонецПроцедуры

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

Запрос = мТекущееПодключение.NewObject("Query");           
Запрос.Текст = “….Текст запроса …”;
Запрос.УстановитьПараметр("НачалоПериода",
НачалоПериода);Запрос.УстановитьПараметр("КонецПериода" , КонецДня(КонецПериода));

Для того, чтобы передать массив субконто, подойдет такой код:

ВидыСубконтоКД = мТекущееПодключение.NewObject("Массив");
ВидыСубконтоКД.Добавить(мТекущееПодключение.ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты);
ВидыСубконтоКД.Добавить(мТекущееПодключение.ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры);
Запрос.УстановитьПараметр("ВидыСубконтоКД", ВидыСубконтоКД);

Обратите внимание, что массив во внешней информационной базе в вышеприведенном примере создается при помощи мТекущееПодключение.NewObject("Массив");

См. также

Комментарии
1. Ярослав Радкевич (WKBAPKA) 201 16.10.12 09:36 Сейчас в теме
надо сказать, что использование V82.Application из негатива несет не только, что могут появляться диалоговые окна при закрытии соединения, а еще жрет памяти больше и медленно загружается, т.к. по сути происходит загрузка всей конфигурации...
2. Ярослав Радкевич (WKBAPKA) 201 16.10.12 09:38 Сейчас в теме
минус за то, что пример как бы не совсем к тематики статьи... да и сильного отличия в коде при подключении через ComConnector или Application нет
3. Андрей Медведев (1cspbru) 178 16.10.12 11:53 Сейчас в теме
Речь не про то, что память жрет, это понятно. Речь о том, что V82.COMConnector работает не стабильно. Один-два раза вы сможете подключиться к данным, потом произойдет вылет. Во всяком случае, на 8.2.15. В анонсе я определил цели статьи - экономия времени того несчастного, который столкнется с данной проблемой. Переключение на Application реально спасает, хотя и менее эффективно
4. Евгений Федоров (FedorovEvg) 147 16.10.12 17:10 Сейчас в теме
Не сталкивался с вылетами в com, можно подробнее описать проблему ?
5. aspirator 23 (aspirator23) 298 17.10.12 07:49 Сейчас в теме
На разных платформах работал. Все же ком всегда работал. Если и были проблемы, то только с кодом, который был неправильно написан и был источником ошибок.
6. Сергей Карташев (Elisy) 860 17.10.12 08:02 Сейчас в теме
7. Андрей Медведев (1cspbru) 178 17.10.12 18:05 Сейчас в теме
Ошибка описана в статье. Я понимаю, что в комментариях звучат некоторые сомнения. Сам бы не поверил. Выгледело примерно так: запускаешь раз пять отчет с разными входными параметрами, потом открываешь, скажем, справочник контрагентов, а эсина вылетает. Либо с сообщением, что потерян ключ защиты, либо по run-time errjr какой-то сишной библиотеки (оную даже админа попросил переставить, не помогло). Еще раз напомню, что речь о 8.2.15. Можно почитать список ошибок платформы на эсовском сайте, там много ошибое с com.

Раньше я то же не сталкивался...
8. Андрей Медведев (1cspbru) 178 17.10.12 18:07 Сейчас в теме
Рад бы, если речь о моей ошибке. Если у кого-то есть абстрактные идеи (код, честно говоря, приводить лень), рад был бы услышать
9. Spi1y (Spi1y) 19.10.12 11:27 Сейчас в теме
Хм, в рабочей базе используется отчет, собирающий по ComConnector данные из примерно 5-6 баз. Самим отчетом регулярно пользуются 2-3 человека. Ни единого репорта не было.
10. Ридван (утюгчеловек) 22.08.13 09:29 Сейчас в теме
Вполне верю автору. От 1С можно такое ожидать.
Сам лично не сталкивался, но и активно моим СОМ-отчетом, намедни написанным, пока не пользовались.
Посему настрожился.

Мне не понятна это предложение:
Окно мне было без надобности, поэтому отключил его вывод на уровне системной записи, под которой происходило подключение к информационной базе.

Можешь расшифровать до уровня элементарных действий? Меня лично это окошко просто выводит из себя.

И еще. Строка типа:
мТекущееПодключение = Неопределено;

Это просто правило хорошего тона? Просто в мануалах сказано что соединение существует пока существует контекст, в котором оно создано. Или я что-то не тек понял?
Оставьте свое сообщение