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

发布于 2024-12-23 17:57:44 字数 1201 浏览 3 评论 0原文

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

根据我从 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 并重新启动它才能恢复)。

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

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...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

孤独陪着我 2024-12-30 17:57:44
  1. 如果threadHANDLE,则使用CloseHandle(thread)清理它,而不是删除线程
  2. 您应该在 Fiber 的构造函数中将 thread 和 Fiber 初始化为 NULL,以保持类的不变量。
  3. 您不能在当前正在执行的纤程上调用DeleteFiber,除非您想终止线程。您可以通过调用 < 来清理它代码>ConvertFiberToThread()
  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()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文