Приложение С++/CLI смешанного режима не выключает CLR правильно
Мое приложение MFC с смешанным режимом создает ложные утечки памяти, потому что у CRT нет времени для закрытия, прежде чем выключение MFC dll будет закрыто.
У меня очень простое небольшое приложение, которое показывает проблему:
#include <windows.h>
#include <iostream>
struct LongTimeToDestroy
{
~LongTimeToDestroy()
{
std::cout << "Will get called!" << std::endl;
Sleep(3000);
std::cout << "Won't get called!" << std::endl;
}
};
LongTimeToDestroy gJamsUpTheCRT;
int main()
{
}
Скомпилируйте с помощью cl.exe /clr test.cpp
. При запуске вы получаете:
Will get called!
Суть проблемы: любые статические/глобальные переменные, объявленные до gJamsUpTheCRT
, не будут освобождены. Например, в моем случае класс MFC CWinApp не очищается.
Является ли это ожидаемым поведением? Я хочу, чтобы приложение полностью отключилось.
Спасибо,
Ответы
Ответ 1
Является ли это ожидаемым поведением?
Да, хотя вы должны прочитать мелкий шрифт в спецификации CLI. Какой promises, что финализаторы на управляемых объектах вызывается, когда программа завершается. Но с оговоркой, что поток финализатора, который делает это, получает две секунды, чтобы выполнить работу. Если это займет больше времени, CLR предполагает, что там что-то совершенно ошибочное. Подобно общему проклятию блокировки кода на объекте синхронизации, который не собирается сигнализировать. С чем это связано, прервав поток финализатора и разрешив программе завершить работу. Нет диагностики.
Вам придется обойти это ограничение.
Ответ 2
Я верю, что отвечает на вашу проблему.
Соответствующий текст:
Несмотря на то, что конфигурация, по умолчанию, CLR позволяет финализаторам работать в течение 2 секунд, прежде чем стать нетерпеливым; если этот тайм-аут превышен, поток финализатора остановлен, и выключение продолжается, не опуская оставшуюся часть очереди финализатора.
Поэтому у вас действительно не должно быть никаких деструкторов, выполняющих задачи, которые потребуют времени.
Изменить: на самом деле это не CLR-класс, поэтому он не должен находиться в очереди финализации? Это может ввести в заблуждение.