У меня есть класс на C++/CLI, который использует неуправляемые ресурсы (HANDLE для собственного потока (т.е. из CreateThread()) и LPVOID для волокна из CreateFiber/ConvertThreadToFiber).
По совету, который я получил от MSDN, я очищаю неуправляемые ресурсы в финализаторе (!Fiber()), а деструктор (~Fiber()) вызывает финализатор.
Вот код:
Fiber::~Fiber () {
this->!Fiber();
}
Fiber::!Fiber () {
if (thread!=NULL) {
delete thread;
thread=NULL;
}
if (fiber!=NULL) {
DeleteFiber(fiber);
fiber=NULL;
}
}
У меня есть тестовое приложение, которое создает два волокна, тестирует их, а затем утилизирует по мере их использования. Первый утилизируется нормально. Последний расположен как последняя строка программы, и он вылетает одним из трех разных способов:
Unhandled Exception: System.AccessViolationException: Attempted to read or write
protected memory. This is often an indication that other memory is corrupt.
at DeleteFiber(Void* )
at System.Threading.Fiber.!Fiber()
at System.Threading.Fiber.Dispose(Boolean )
at System.Threading.Fiber.Finalize()
Эта ошибка также может исходить из строки:
delete thread;
Также.
Он также может вылететь с OutOfMemoryException или зависнуть на некоторое время, говоря, что программа испытала переполнение стека, а затем зависнуть консоль (мне нужно закрыть cmd.exe и перезапустить его для восстановления).
Если я закомментирую деструктор/финализатор и запущу программу, она будет работать отлично, но это не вариант, потому что я не хочу, чтобы неуправляемые ресурсы зависали до тех пор, пока программа не завершится...