终结器引发随机异常,引发随机错误,挂起应用程序

时间:2011-12-29 19:05:30

标签: .net c++-cli destructor finalizer

我在C ++ / CLI中有一个使用非托管资源的类(本机线程的HANDLE(即来自CreateThread())和来自CreateFiber / ConvertThreadToFiber的光纤的LPVOID。

根据我从MSDN获得的建议,我正在清理终结器中的非托管资源(!Fiber()),析构函数(~Fibper())正在调用终结器。

以下是代码:

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并重新启动才能恢复)。

如果我对析构函数/终结器进行注释,并运行该程序,它运行完美,但这不是一个选项,因为我不希望在程序结束之前暂停非托管资源...

1 个答案:

答案 0 :(得分:1)

  1. 如果threadHANDLE,则使用CloseHandle(thread)进行清理,而不是delete thread
  2. 您应该在thread的构造函数中初始化fiberNULLFiber,以维护该类的不变量。
  3. 除非您要终止线程,否则无法在当前正在执行的光纤上调用DeleteFiber。您可以致电ConvertFiberToThread()
  4. 进行清理