FatalExecutionEngineError は、複数の AppDomains と共に COM 呼び出しを実行するときに発生します

この記事は、コンポーネント オブジェクト モデル (COM) 呼び出しを複数の AppDomains と共に実行すると 、FatalExecutionEngineError エラーがスローされる可能性がある問題を解決するのに役立ちます。

元の製品バージョン: .NET Framework 4.5
元の KB 番号: 2997900

現象

ASP.NET アプリケーションで、複数の AppDomains を作成し、省略可能なパラメーターの値を指定せずに を使用して省略可能なパラメーターを使用 IDispatch::Invoke してメソッドを開始すると、アプリケーションがクラッシュし、次のエラー メッセージが表示される場合があります。

マネージド デバッグ アシスタント FatalExecutionEngineError で、xxx.exe で問題が検出されました。 追加情報: ランタイムで致命的なエラーが発生しました。 エラーのアドレスは、スレッド 0x20a8の0x0e888517でした。 エラー コードが0xc0000005。

原因

.NET では、メソッド呼び出しが行われる最初 AppDomain ので内部 GC ハンドルが作成され、使用されている AppDomain に関係なく、アプリケーションの有効期間を通じて同じ内部 GC ハンドルが再利用されます。 これがアンロードされると、アプリケーションがクラッシュ AppDomain する可能性があります。

回避策

この問題を回避するには、コード例として共有された変更を実装します。

[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface ITestInterface
{
    .
    .
}

これを行うには、次の手順に従います。

  1. の代わりに、提供されたITypeInfoオペレーティング システムの実装を使用するようにアセンブリ レベルIDispatchImplAttribute(IDispatchImplType.CompatibleImpl)を適用します。NET の実装:

    [assembly:IDispatchImplAttribute(IDispatchImplType.CompatibleImpl)]
    

    または、 を介してアクセスする必要がある任意の型にこのような属性を IDispatch適用することもできます。

  2. オペレーティング システムが提供ITypeInfoする実装では純粋なディスパッチ インターフェイスがサポートされていないため、インターフェイスの種類を にInterfaceIsDual変更します。

  3. インターフェイスをパブリックにして COM に表示し、インターフェイスが実際に型 lib に表示され、対応する typeinfo が型 lib に表示されるようにします。