2012-04-19 17 views
1

MFC dllがシャットダウンされる前にCRTにシャットダウンする時間がないため、混在モードのMFCアプリケーションで誤ったメモリリークが発生しています。混在モードのC++/CLIアプリケーションでCLRが正しくシャットダウンされない

私は問題を示し、非常に単純な小さなアプリケーションがあります。

#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派生クラスはクリーンアップされません。

これが期待どおりの動作ですか?私は私のアプリケーションが完全にシャットダウンすることを許可したいと思います。

おかげで、

答えて

2

この現象は予期しないものですか?

はい、CLIの仕様で細かい部分を読む必要があります。これは、プログラムの終了時にマネージオブジェクトのファイナライザが呼び出されることを約束します。しかし、これを行うファイナライザスレッドが2秒かかると警告が表示されます。時間がかかると、CLRは、何かが大幅に間違っているとみなします。シグナルを受け取らない同期オブジェクトでコードブロックを行うという一般的な呪いのように。これはによって処理され、ファイナライザスレッドを終了し、プログラムを終了させます。診断はありません。

この制限を回避する必要があります。

+0

Porgesのリンクで提供されているJoe Duffyリンクは、「設定は可能ですが、デフォルトではCLRによってファイナライザが2秒間実行される」と述べています。あなたはこれを設定する方法を知っていますか? – Cechner

+0

いいえ、おそらくあなた自身がCLRをホストする以外の方法ではありません。現実的には、ファイナライザーが既に50億cpuのサイクルを焼いていて、仕事をやり遂げなかったときに、もう少し追加することで救済する可能性はあまりありません。 –

1

私はthis answers your problemを信じています。

関連するテキスト:

設定可能なものの、デフォルトでCLRは、ファイナライザはせっかちになる前に2秒間に実行できるようになります。このタイムアウトを超えるとファイナライザスレッドが停止し、ファイナライザキューの残りの部分を排水せずにシャットダウンを続行します。

だから、あなたは本当に時間を要するタスクを実行するデストラクタを持つべきではありません。

編集:実際には、CLRクラスではないので、ファイナライズキューに入れてはいけませんか?これは誤解を招く可能性があります。

+0

これは極端なようです - どうすれば設定できますか?私のシナリオ(C + +/CLIのlibに静的にリンクしているMFC)は普通ではないと推測しています.-これは、C++/CLIのすべてのものをMFCのdllに入れ、 – Cechner

+0

あなたの編集にもう少し注意してください:CRTクリーンアップはメインモジュール '.cctor'によって処理されているようですが、このクリーンアップは 'finalizer queue'のどこかに配置されていると思います。 – Cechner

関連する問題