この記事は、別の WPF ウィンドウをインスタンス化しようとすると、1 つの Windows Presentation Foundation (WPF) ウィンドウを閉じた後にハンドルされない例外が発生する問題を解決するのに役立ちます。
元の製品バージョン: Visual Studio Professional 2010
元の KB 番号: 2691806
症状
Microsoft .NET 3.5 WPF コンポーネントを開発し、WINDOWS フォーム アプリケーションやネイティブ アプリケーションなど、WPF ベース以外のクライアント アプリケーションでホストしました。 クライアント アプリケーションは WPF コンポーネントを呼び出して、カスタム WPF ウィンドウをインスタンス化して表示します。 Windows の最初のインスタンス化が想定どおりに表示されます。 ただし、Window を閉じて別の WPF ウィンドウをインスタンス化しようとすると、ハンドルされない例外が発生します。
Visual Studio IDE でアプリケーションを実行すると、次の例外と呼び出し履歴が表示されます。
System.ExecutionEngineException: Exception of type 'System.ExecutionEngineException' was thrown.
WindowsBase.dll!MS.Internal.Invariant.FailFast(string message, string detailMessage)
WindowsBase.dll!MS.Internal.Invariant.Assert(bool condition, string invariantMessage)
PresentationFramework.dll!System.Windows.Application.GetResourceOrContentPart(System.Uri uri)
PresentationFramework.dll!System.Windows.Application.LoadComponent(object component, System.Uri resourceLocator)
WPFClassLibrary.dll!WPFClassLibrary.WPFWindow.InitializeComponent()
WPFClassLibrary.dll!WPFClassLibrary.WPFWindow.WPFWindow()
WPFClassLibrary.dll!WPFClassLibrary.WPFManager.ShowWpfWindow()
WindowsFormsApplication1.exe!WindowsFormsApplication1.Form1.button1_Click(object sender, System.EventArgs e)
Windbg などのネイティブ デバッガーでアプリケーションを実行すると、次の呼び出し履歴でブレークポイント例外が発生します。
eax=00000001 ebx=00000000 ecx=00000001 edx=001becbc esi=79aedfd0 edi=577ac529
eip=76c3280c esp=001be81c ebp=001becc8 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
KERNELBASE!DebugBreak+0x2: 76c3280c cc int 3
0:000> knL
# ChildEBP RetAddr
00 001be818 797cd3a7 KERNELBASE!DebugBreak+0x2
01 001becc8 797cd6e0 mscorwks!EEPolicy::LogFatalError+0x2b5
02 001bece0 797d58f4 mscorwks!EEPolicy::HandleFatalError+0x4d
03 001bed94 577ac529 mscorwks!SystemNative::FailFast+0x142
04 001bed9c 57877ec1 WindowsBase_ni!MS.Internal.Invariant.FailFast(System.String, System.String)+0x35
05 001bedbc 55b5ea77 WindowsBase_ni!MS.Internal.Invariant.Assert(Boolean, System.String)+0x219ca1
06 001bedbc 55b5d935 PresentationFramework_ni!System.Windows.Application.GetResourceOrContentPart(System.Uri)+0x87
07 001bede4 003e0589 PresentationFramework_ni!System.Windows.Application.LoadComponent(System.Object, System.Uri)+0xc5
08 001bedfc 003e04f8 WPFClassLibrary!WPFClassLibrary.WPFWindow.InitializeComponent()+0x79
09 001bee08 003e046e WPFClassLibrary!WPFClassLibrary.WPFWindow..ctor()+0x28
0a 001bee24 003e03dc WPFClassLibrary!WPFClassLibrary.WPFManager.ShowWpfWindow()+0x76
0b 001bee34 7aec4170 WindowsFormsApplication1!WindowsFormsApplication1.Form1.button1_Click(System.Object, System.EventArgs)+0x2c
原因
クラッシュ現象は、アプリケーションが WPF ウィンドウまたは UserControl に関連付けられた XAML ファイルを読み込む System.Windows.Application.LoadComponent
メソッドを呼び出すときに発生します。 最終的に、WPF ランタイムは System.Windows.Application.GetResourceOrContentPart
を呼び出して、現在の System.Windows.Application
オブジェクトに関連付けられているリソース パッケージを読み込みます。
このエラーは、現在の System.Windows.Application
オブジェクトに関連付けられているリソース パッケージを取得できなかったために発生します。 これは通常、現在の System.Windows.Application
オブジェクトが、 Application.ShutDown
の明示的または暗黙的な呼び出しによって既にシャットダウンされているために発生します。
この動作は設計によるものです。
解決策
System.Windows.Application
オブジェクトのインスタンスを作成するときは、そのShutDownMode
プロパティを ShutDownMode.OnExplicitShutdown
に設定します。 これにより、カスタム コードが明示的にApplication
を呼び出した結果として、Application.ShutDown
オブジェクトをシャットダウンすることのみが許可されます。
詳細情報
Application.ShutDown
メソッドが呼び出されると、WPF ランタイムは、そのApplication
オブジェクトに関連付けられているリソース パッケージをアンロードします。 後で、同じ Application
オブジェクトに関連付けられているリソースにアクセスする必要がある処理をアプリケーションが実行した場合、 System.Windows.Application.GetResourceOrContentPart
メソッドはこれらのリソース パッケージの読み込みを試みますが、以前にアンロードされたために読み込むことができません。 WPF はこれを検出すると、致命的な状態と見なされ、WPF は意図的に System.Environment.FailFast
を呼び出し、 System.ExecutionEngineException
をスローしてプロセスを終了します。
クライアント アプリケーションは、AppDomain ごとに System.Windows.Application
(または派生) 型のインスタンスを 1 つ作成できます。
Application.ShutDown
メソッドが呼び出されると、その Application オブジェクトに関連付けられているリソースがアンロードされます。
Application.ShutDown
メソッドは、カスタム コードによって明示的に呼び出されるか、Application.ShutDownMode
プロパティの値に基づいて WPF ランタイムによって内部的に呼び出される場合があります。 既定では、ShutDownMode
オブジェクトの Application
プロパティは ShutDownMode.OnLastWindowClose
に設定されます。 これにより、そのApplication
オブジェクトに関連付けられた最後の WPF ウィンドウが閉じられた後、WPF ランタイムによってApplication
オブジェクトが自動的にシャットダウンされます。 クライアント アプリケーションが WPF Application
オブジェクトのインスタンスを作成し、ウィンドウを表示して閉じたシナリオでは、そのウィンドウは最後に閉じられたウィンドウと見なされるため、WPF は自動的に Application.ShutDown
を呼び出します。