终结者抛出随机异常,引发随机错误,挂应用程序 [英] Finalizer Throws Random Exceptions, Raises Random Errors, Hangs App

查看:246
本文介绍了终结者抛出随机异常,引发随机错误,挂应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



根据我从 MSDN 获得的建议, m清除finalizer中的非托管资源(!Fiber()),析构函数(〜Fiber())调用终结器。



/ p>

  Fiber ::〜Fiber(){

this->!Fiber

}


Fiber ::!Fiber(){

if(thread!= NULL){

删除线程;
thread = NULL;

}

if(fiber!= NULL){

DeleteFiber(fiber);
fibre = NULL;

}

}

测试应用程序创建两个光纤,测试它们,然后处理它们与他们做。第一个被安排好了。最后一个被处理为程序的最后一行,并以三种不同的方式崩溃:

 未处理的异常:System.AccessViolationException:尝试读取或写入
受保护的内存。这通常表明其他内存已损坏。
在System.Threading.Fiber中的DeleteFiber(Void *)
!Fiber()
System.Threading.Fiber.Dispose(Boolean)
在System.Threading.Fiber .Finalize()

这个错误也可以从下面这行:

 删除线程; 

以及。



与OutOfMemoryException崩溃,或挂起一段时间,说该程序经历了一个堆栈溢出,然后挂控制台(我必须关闭cmd.exe并重新启动它恢复)。



如果我注释析构函数/终结器,并运行程序,它运行完美,但这不是一个选项,因为我不希望非托管资源挂起,直到程序结束...

解决方案


  1. 如果线程 HANDLE ,用 CloseHandle(thread),而不是删除线程清理它。

  2. 您应该初始化线程 fiber c

  3. 在当前执行的光纤上调用 DeleteFiber ,除非你想终止线程。您可以通过调用 ConvertFiberToThread()


I have a class in C++/CLI that uses unmanaged resources (a HANDLE for a native thread (i.e. from CreateThread()) and an LPVOID for a fiber from CreateFiber/ConvertThreadToFiber).

Under the advice I got from MSDN I'm cleaning up the unmanaged resources in the finalizer (!Fiber()), and the destructor (~Fiber()) is calling the finalizer.

Here's the code:

Fiber::~Fiber () {

    this->!Fiber();

}


Fiber::!Fiber () {

    if (thread!=NULL) {

        delete thread;
        thread=NULL;

    }

    if (fiber!=NULL) {

        DeleteFiber(fiber);
        fiber=NULL;

    }

}

I have a test app that creates two fibers, tests them, and then disposes them as it's done with them. The first one is disposed just fine. The last one is disposed as the last line of the program, and it crashes out in one of three different ways:

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()

That error can also come from the line:

delete thread;

As well.

It may also crash with an OutOfMemoryException, or by hanging for a while, saying that the program experienced a stack overflow, and then hanging the console (I have to close cmd.exe and restart it to recover).

If I comment the destructor/finalizer out, and run the program, it runs perfectly, but that's not an option because I don't want unmanaged resources hanging around until the program ends...

解决方案

  1. If thread is a HANDLE, you clean it up with CloseHandle(thread), not delete thread.
  2. You should initialize thread and fiber to NULL in Fiber's constructor, to maintain the invariants of the class.
  3. You can't call DeleteFiber on the currently executing fiber, unless you want to terminate the thread. You clean it up by calling ConvertFiberToThread()

这篇关于终结者抛出随机异常,引发随机错误,挂应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆