web-dev-qa-db-ja.com

基礎となるRCWから分離されたCOMオブジェクトは使用できません

C#dllから呼び出すCOMコンポーネントがあります。

また、その.dllを使用するwinformsアプリもあります。

アプリを閉じると、次の例外が発生します。

基礎となるRCWから分離されたCOMオブジェクトは使用できません。

スタックトレースは、この例外が.dllのデストラクタに由来することを示しています。このデストラクタを実装して、COMのクリーンアップメソッドを呼び出しました。

なぜこれが起こるのですか?どのように解決するのが最善ですか?

44
Yaron Naveh

問題は次のとおりです。

ファイナライザからRCWを呼び出すのは安全ですか?

そしてここ:

デストラクタでExcelオブジェクトをリリース

問題は、これらのオブジェクトをガベージコレクションするタイミングが不確実であるだけでなく、ファイナライザが呼び出される順序も非決定的であるということです。この場合、Runtime Callable Wrapperには、それ自体でMarshal.FinalReleaseComObjectを呼び出すファイナライザーもあります。ファイナライザーは、このCOMオブジェクトを解放できるように、フェンスのCOM側で参照カウントをデクリメントします。ただし、ファイナライザが呼び出される順序は不明確であるため、オブジェクトが参照するCOMオブジェクトのファイナライザは、オブジェクトのファイナライザの前に起動する可能性が非常に高くなります。そのため、ファイナライザ内のコードは時々動作する可能性がありますが、ほとんどの場合、オブジェクト参照の1つまたは複数のRuntime Callable Wrappersにはすでにファイナライザが呼び出されており、ファイナライザに到達する前に基礎となるCOMオブジェクトがリリースされていますそのコードを実行します。

33
Ran