Разработка и Конфигурация · 11 мин
Как закрыть COM-соединение в 1С 8.3
Как корректно закрыть COM-соединение в 1С 8.3: обнуление объекта V83.COMConnector, завершение процессов dllhost и 1cv8, типичные ошибки и проверка результата.
COM-соединение в 1С 8.3 создаётся через объект V83.COMConnector (или V82.COMConnector для старых платформ) и позволяет одной базе подключаться к другой, а также внешним приложениям — обращаться к данным 1С. Проблема в том, что простое присвоение переменной значения Неопределено далеко не всегда освобождает ресурсы: сеанс в базе-источнике продолжает висеть, а процессы dllhost.exe и 1cv8.exe остаются в памяти.
Незакрытые соединения приводят к вполне практическим последствиям: к блокировкам при попытке монопольного доступа, к расходу лицензий, к росту числа «спящих» сеансов в консоли кластера и к ошибкам при повторном подключении. Поэтому закрытие COM-соединения нужно делать явно и проверять результат, а не полагаться на сборщик мусора.
Ниже разобраны рабочие способы закрытия соединения: штатное обнуление объектов, завершение процессов операционной системы, удаление сеансов через консоль кластера, а также типичные ошибки и способы проверки, что соединение действительно освобождено.
Как устроено COM-соединение и почему оно «зависает»
При создании COM-соединения фактически участвуют два объекта: сам коннектор V83.COMConnector и объект соединения, возвращаемый методом Connect(). Коннектор — это COM-компонент, зарегистрированный в операционной системе, а соединение — отдельный экземпляр, внутри которого запускается полноценный сеанс работы с информационной базой.
Для файловой базы подключение выполняется через строку вида File="C:\Bases\Trade";Usr="Администратор";Pwd="123", для клиент-серверной — через Srvr="Server1";Ref="Trade";Usr="...";Pwd="...". В обоих случаях на стороне базы-источника создаётся полноценный сеанс, который занимает лицензию и виден в консоли кластера или в списке активных пользователей.
«Зависание» происходит по простой причине: COM-объекты живут по правилам подсчёта ссылок Windows, а не по правилам сборки мусора 1С. Пока существует хотя бы одна живая ссылка на объект соединения — в переменной, в реквизите формы, в глобальном контексте, в кэше внешней обработки — сеанс не завершится, даже если код, создававший соединение, давно отработал.
Штатное закрытие соединения в коде 1С
Основной и самый надёжный способ — явно обнулить оба объекта в том же коде, где они создавались. Порядок важен: сначала освобождается соединение, затем коннектор. Обратный порядок может оставить «осиротевший» сеанс.
// Создание соединения
Коннектор = Новый COMОбъект("V83.COMConnector");
Соединение = Коннектор.Connect("File=""C:\Bases\Trade"";Usr=""Админ"";Pwd=""123""");
// ... работа с данными ...
// Закрытие: сначала соединение, потом коннектор
Соединение = Неопределено;
Коннектор = Неопределено;
Если соединение создаётся внутри процедуры в локальных переменных, оно формально должно освободиться при выходе из процедуры. На практике это срабатывает не всегда — особенно если объект был передан в другие процедуры или сохранён в реквизитах. Поэтому явное обнуление в блоке Попытка...Исключение...КонецПопытки считается хорошей практикой: закрытие размещают в конце блока Попытка и дублируют в обработчике исключения, чтобы соединение не осталось при ошибке.
Отдельный случай — соединение, хранящееся в реквизите формы или в глобальной переменной модуля для повторного использования. Такой подход допустим, но тогда закрывать его нужно в обработчике закрытия формы (ПриЗакрытии) или при завершении работы сеанса, иначе сеанс в базе-источнике проживёт столько же, сколько открыта форма.
- 1Завершите все операции чтения и записи через соединение
- 2Присвойте переменной соединения значение Неопределено
- 3Присвойте переменной коннектора значение Неопределено
- 4Продублируйте обнуление в ветке Исключение блока Попытка
- 5Проверьте в консоли кластера, что сеанс исчез из списка активных
Завершение процессов операционной системы
Когда код уже отработал, а сеанс остался, помогает завершение процессов на стороне того компьютера, где создавалось COM-соединение. Для файловой базы и толстого клиента это обычно процесс 1cv8.exe или 1cv8c.exe вызывающего приложения. Если соединение создавалось из внешнего приложения (скрипта, Excel, сторонней программы), COM-объект может размещаться в суррогатном процессе dllhost.exe.
Завершить процесс можно через Диспетчер задач (вкладка «Подробности» → найти процесс → «Снять задачу») или командой taskkill. Важно понимать, чей это процесс: завершение чужого 1cv8.exe оборвёт работу пользователя без сохранения данных.
taskkill /F /IM dllhost.exeКоманда taskkill /F /IM dllhost.exe завершит все суррогатные процессы COM+, включая те, что могут использоваться другими приложениями. Более точечный вариант — найти конкретный PID через Диспетчер задач и завершить его: taskkill /F /PID 12345. После завершения процесса сеанс в клиент-серверной базе исчезнет не мгновенно: кластер удалит его по таймауту, обычно в течение нескольких минут.
Удаление сеанса через консоль кластера
Если база-источник работает в клиент-серверном режиме, администратор может удалить зависший сеанс напрямую. Для этого откройте консоль администрирования серверов 1С, разверните нужный кластер, перейдите в ветку «Сеансы» и найдите сеанс с приложением вида «COM-соединение» (в колонке «Приложение» отображается именно такое название) и именем пользователя, под которым выполнялось подключение.
Выделите сеанс и выберите в контекстном меню «Удалить». Сеанс завершится немедленно, соединение на стороне вызывающего кода станет нерабочим — при следующем обращении к нему возникнет ошибка. Это нормально, если вызовы уже завершены.
Дополнительно стоит проверить ветку «Соединения» той же консоли: там видно, какой рабочий процесс кластера обслуживает соединение. Если зависших сеансов много и они регулярно появляются от одного и того же регламентного задания или обработки — проблему нужно решать в коде, а не ручной чисткой.
Профилактика: как не допускать зависших соединений
Самая частая причина зависаний — архитектура «создал соединение и забыл». Несколько практических мер заметно снижают число таких ситуаций. Во-первых, создавайте соединение как можно ближе к месту использования и закрывайте в том же методе — это локализует время жизни объекта. Во-вторых, всегда оборачивайте работу с соединением в Попытка/Исключение с обнулением в обеих ветках.
В-третьих, для регулярных обменов рассмотрите альтернативы COM: HTTP-сервисы, веб-сервисы, файловый обмен или планы обмена. Эти механизмы управляют сеансами штатно и не требуют ручного контроля времени жизни COM-объектов. COM-соединение оправдано в основном для разовых выгрузок и сценариев, где нужен прямой доступ к объектной модели другой базы.
Сравнение вариантов закрытия
Штатный и безопасный способ. Подходит всегда, когда есть доступ к коду. Ограничение: не работает, если ссылка на объект потеряна или код завершился аварийно.
Помогает при зависшем клиенте или внешнем приложении. Риск: обрывает все соединения процесса, данные не сохраняются.
Точечное завершение со стороны сервера. Требует прав администратора кластера и доступно только в клиент-серверном режиме.
Типичные ошибки при закрытии COM-соединения
Ошибки в этой теме повторяются из проекта в проект. Самая распространённая — обнуление только соединения при живом коннекторе или наоборот: оба объекта должны быть освобождены. Вторая частая ошибка — хранение соединения в реквизите формы без закрытия в ПриЗакрытии: форма закрылась, а сеанс в базе-источнике остался.
Третья ошибка — попытка «переиспользовать» соединение после того, как оно было разорвано сервером по таймауту. Такой объект выглядит живым, но любое обращение к нему вызывает исключение. Правильный подход — пересоздавать соединение заново. Четвёртая ошибка — создание соединения на сервере 1С в фоновом задании без учёта того, что COM-компонент должен быть зарегистрирован именно на сервере, а не на клиентской машине разработчика.
Как проверить, что соединение действительно закрыто
После закрытия стоит убедиться, что ресурсы освобождены. Для клиент-серверной базы основной контроль — консоль кластера: сеанс с приложением «COM-соединение» должен исчезнуть из списка. Учтите, что после принудительного завершения процесса сеанс может отображаться ещё несколько минут, пока кластер не зафиксирует обрыв.
Для файловой базы проверка проще: файл 1Cv8.1CL (журнал сеансов) и наличие лишних процессов 1cv8.exe в Диспетчере задач. Если после закрытия своего приложения лишний процесс 1С остался — соединение не было освобождено корректно. Дополнительный признак успеха — возможность открыть базу монопольно: зависший COM-сеанс блокирует установку монопольного режима так же, как обычный пользовательский сеанс.
Как проверить результат
Сеанс с приложением «COM-соединение» отсутствует
Сеанс висит спустя несколько минут после закрытия
Лишних процессов 1cv8.exe и dllhost.exe нет
Процесс остался после завершения приложения
Монопольный режим устанавливается без ошибок
Ошибка «база используется другими сеансами»
Что важно запомнить
COM-соединение закрывается явным обнулением обоих объектов — соединения и коннектора — желательно в блоке Попытка/Исключение. Если сеанс завис, его завершают через Диспетчер задач или консоль кластера. Результат проверяют по списку сеансов и возможности монопольного доступа.
Частые вопросы о закрытии COM-соединений
Достаточно ли присвоить соединению Неопределено, чтобы сеанс закрылся?
Не всегда. Если на объект соединения осталась хотя бы одна ссылка — в реквизите формы, глобальной переменной, кэше обработки — сеанс продолжит существовать. Нужно обнулить и соединение, и коннектор, убедившись, что других ссылок на объекты нет.
Почему сеанс в консоли кластера не исчезает сразу после закрытия?
Кластер серверов 1С удаляет оборванные сеансы не мгновенно, а по внутреннему таймауту — обычно в течение нескольких минут. Если сеанс висит существенно дольше, значит соединение на клиентской стороне не было освобождено.
Чем завершение сеанса в консоли кластера отличается от завершения процесса?
Удаление сеанса в консоли — точечное действие на стороне сервера: обрывается только выбранный сеанс, клиентский процесс при этом продолжает работать. Завершение процесса на клиенте убивает всё приложение целиком, включая несохранённые данные.
Можно ли закрыть COM-соединение из кода базы-источника?
Напрямую из кода базы-источника закрыть чужое COM-соединение нельзя — оно управляется вызывающей стороной. Административный вариант — завершить сеанс через программный интерфейс администрирования кластера (COM-объект V83.ComAdmin или агент сервера).
Что делать, если COM-соединения зависают регулярно?
Регулярные зависания указывают на ошибку в коде: соединение не обнуляется при исключениях или хранится в долгоживущих объектах. Найдите место создания соединения, добавьте обнуление в обе ветки Попытка/Исключение. Если обмен регулярный — рассмотрите переход на HTTP-сервисы вместо COM.
Занимает ли зависший COM-сеанс лицензию 1С?
Да. COM-соединение создаёт полноценный сеанс, который расходует клиентскую лицензию наравне с обычным пользовательским сеансом. Массовые зависшие соединения могут исчерпать лицензии и заблокировать вход пользователей.