이 문서는 다른 WPF 창을 인스턴스화하려고 하면 WPF(Windows Presentation Foundation) 창을 닫은 후 처리되지 않은 예외가 발생하는 문제를 해결하는 데 도움이 됩니다.
원래 제품 버전: Visual Studio Professional 2010
원래 KB 번호: 2691806
증상
Microsoft .NET 3.5 WPF 구성 요소를 개발하고 Windows Forms 애플리케이션 또는 네이티브 애플리케이션과 같은 비 WPF 기반 클라이언트 애플리케이션에서 호스팅했습니다. 클라이언트 애플리케이션은 WPF 구성 요소를 호출하여 사용자 지정 WPF 창을 인스턴스화하고 표시합니다. Windows의 첫 번째 인스턴스화는 예상대로 표시됩니다. 그러나 창을 닫고 다른 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하여 프로세스를 throw System.ExecutionEngineException 하고 종료합니다.
클라이언트 애플리케이션은 AppDomain당 (또는 파생된) 형식의 System.Windows.Application 인스턴스를 하나 만들 수 있습니다. 메서드가 호출될 때 해당 Application 개체와 연결된 리소스가 Application.ShutDown 언로드됩니다. 메서드는 Application.ShutDown 사용자 지정 코드에 의해 명시적으로 호출되거나 속성 값 Application.ShutDownMode 에 따라 WPF 런타임에 의해 내부적으로 호출될 수 있습니다. 기본적으로 개체의 ShutDownModeApplication 속성은 .로 설정됩니다 ShutDownMode.OnLastWindowClose. 이렇게 하면 해당 개체와 연결된 마지막 WPF 창이 Application 닫힌 후 WPF 런타임이 개체를 Application 자동으로 종료합니다. 클라이언트 애플리케이션이 WPF Application 개체의 인스턴스를 만들고 창을 표시하고 닫은 시나리오에서 해당 창은 마지막 창이 닫힌 것으로 간주되므로 WPF가 자동으로 호출 Application.ShutDown됩니다.