【问题标题】:Mixed-mode C++/CLI app not shutting down CLR correctly混合模式 C++/CLI 应用程序未正确关闭 CLR
【发布时间】:2012-04-30 11:41:52
【问题描述】:

我的混合模式 MFC 应用程序正在创建错误的内存泄漏,因为在 MFC dll 关闭之前 CRT 没有时间关闭。

我有一个非常简单的小应用程序可以显示问题:

#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 派生类没有被清理。

这是预期的行为吗?我想让我的应用完全关闭。

谢谢,

【问题讨论】:

    标签: .net mfc c++-cli mixed-mode


    【解决方案1】:

    这是预期的行为吗?

    是的,尽管您必须阅读 CLI 规范中的细则。它承诺在程序终止时调用托管对象的终结器。但需要注意的是,执行此操作的终结器线程需要两秒钟才能完成工作。如果需要更长的时间,则 CLR 会假定存在严重错误。就像在不会收到信号的同步对象上阻塞代码的常见诅咒一样。它通过中止终结器线程并允许程序终止来处理它。没有诊断。

    你必须解决这个限制。

    【讨论】:

    • Porges 给出的链接中提供的 Joe Duffy 链接说“虽然可配置,但默认情况下 CLR 会让终结器运行 2 秒”。你知道如何配置吗?
    • 没有。除了自己托管 CLR,也许。实际上,当你的终结器已经消耗了 50 亿个 cpu 周期并且没有完成工作时,再添加一些不太可能带来缓解。
    【解决方案2】:

    我相信this answers your problem

    相关文字:

    虽然可配置,但默认情况下,CLR 会让终结器运行 2 秒,然后变得不耐烦;如果超过此超时,终结器线程将停止,并继续关闭而不耗尽终结器队列的其余部分。

    所以你真的不应该让任何析构函数执行需要时间的任务。

    编辑:实际上,这不是 CLR 类,所以它不应该在终结队列中?这可能会产生误导。

    【讨论】:

    • 这似乎很极端——如何配置?我猜我的场景(MFC 静态链接到 C++/CLI 库)并不常见 - 如果我将所有 C++/CLI 内容放入 MFC dll 并与之链接,这会得到纠正吗?
    • 进一步说明您的编辑:CRT 清理似乎是由主模块“.cctor”处理的,我想这会将清理放在其“终结器队列”中的某个位置。
    猜你喜欢
    • 2010-11-08
    • 2017-07-22
    • 1970-01-01
    • 1970-01-01
    • 2010-11-07
    • 1970-01-01
    • 1970-01-01
    • 2015-04-27
    • 2014-07-06
    相关资源
    最近更新 更多