Нередко разработчики сталкиваются с ситуацией, когда после закрытия пользовательского интерфейса процесс платформы (1cv8.exe или 1cv8c.exe) продолжает висеть в диспетчере задач Windows. Чаще всего подобное поведение наблюдается при активной работе с самописными или сторонними динамическими библиотеками (DLL), подключенными по технологии COM. Разберем по шагам, почему очистка переменных в коде 1С не всегда помогает и как гарантированно решить данную проблему.
В коде 1С общепринятой практикой для освобождения COM-объекта является присвоение переменной значения Неопределено. Однако этого бывает недостаточно, если удерживаются внутренние ресурсы операционной системы. Проанализируем основные причины, по которым процесс не может завершиться:
DllMain при событии DLL_PROCESS_DETACH приводит к блокировке загрузчика Windows (Loader Lock), в результате чего процесс навсегда замирает в памяти.OleMainThreadWnd), зависание сообщений в которых блокирует выгрузку.Прежде чем менять программный код, необходимо точно локализовать источник проблемы. Рассмотрим, как провести диагностику:
1cv8c.exe и откроем нижнюю панель со списком дескрипторов (Handles) и загруженных библиотек (DLLs). Это позволит увидеть, удерживает ли исследуемая DLL открытые файлы, мьютексы или системные события.AddRef и Release, чтобы проверить баланс ссылок.Если проблема вызвана особенностями взаимодействия платформы с библиотекой при закрытии сеанса, можно применить программное принудительное завершение. Рассмотрим реализацию в модуле управляемого приложения.
В процедуре ПередЗавершениемРаботы или ПриЗавершенииРаботы вызовем метод принудительного закрытия:
Процедура ПередЗавершениемРаботы(Отказ)
// Освобождаем ссылку на COM-объект
МойCOMОбъект = Неопределено;
// Завершаем работу системы в безусловном режиме
ЗавершитьРаботуСистемы(Истина);
КонецПроцедуры
Если даже после этого процесс остается в памяти, можно применить более жесткий платформенный метод ПрекратитьРаботуСистемы(), который производит немедленную деинициализацию клиентского приложения без интерактивных подтверждений:
Процедура ПриЗавершенииРаботы()
МойCOMОбъект = Неопределено;
ПрекратитьРаботуСистемы();
КонецПроцедуры
Чтобы нестабильная работа внешней библиотеки не влияла на стабильность и выгрузку клиентского приложения 1С, рекомендуется использовать более надежные варианты интеграции:
dllhost.exe. Даже если внутри нее останутся невыгруженные потоки, клиент 1С закроется мгновенно.