2011-12-29 15 views
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; 

    } 

} 

私は、2本のファイバを作成し、それらをテストし、それが彼らと一緒に行うのようにそれらを配置するテストアプリを持っています。最初のものは上手く配置されています。最後の1は、プログラムの最後の行に配置され、そしてそれは、3つの異なる方法のいずれかで出てクラッシュさ:

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を閉じて回復する必要があります)。

私はデストラクタ/ファイナライザをコメントし、プログラムを実行した場合、それは完璧に動作しますが、プログラムが終了するまで、私はアンマネージリソースをぶらぶらしたくないので、それはオプションではありません...

+0

DeleteFiber()メソッドの外観はどうなっていますか? –

+0

[これに似ています。](http://msdn.microsoft.com/en-us/library/windows/desktop/ms682556(v = VS.85).aspx) –

答えて

1
  1. threadHANDLEの場合、CloseHandle(thread)ではなくdelete threadでクリーンアップします。
  2. クラスの不変量を維持するには、とfiberNULLFiberに初期化する必要があります。
  3. スレッドを終了しない限り、現在実行中のファイバでDeleteFiberを呼び出すことはできません。 ConvertFiberToThread()
+0

興味深い。しかし、問題は解決しません。私はまだDeleteFiberからAccessViolationExceptionsを取得しています。 –

+0

コンストラクタは#2で述べたことの両方を行います。私はDispose()を別のファイバー(最初のケース)から呼び出し、次にC#プログラムのMain()メソッド(別のスレッドの2番目のケース)から呼び出します。 –

+0

#3は間接的な解決策でした。スレッドをきれいにしてスレッドから作られたファイバーをクリーンアップしようとすると、まずファイバーが無効になります。解決策は、 'ThreadF'が' NULL'の場合にのみ 'DeleteFiber'が実行されるようにコードを変更することでした。 –

関連する問題