通过


显示 WPF 窗口时发生 System.ExecutionEngineException

本文可帮助你解决以下问题:尝试实例化另一个 WPF 窗口会导致关闭一个 Windows Presentation Foundation (WPF) 窗口后出现未经处理的异常。

原始产品版本: Visual Studio Professional 2010
原始 KB 数: 2691806

症状

你已开发Microsoft .NET 3.5 WPF 组件并将其托管在非基于 WPF 的客户端应用程序中,例如Windows 窗体应用程序或本机应用程序。 客户端应用程序调用 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

原因

当应用程序调用 System.Windows.Application.LoadComponent 方法以加载与 WPF 窗口或 UserControl 关联的 XAML 文件时,会出现崩溃症状。 最终,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 类型(或派生)类型的实例。 调用该方法时 Application.ShutDown ,将卸载与该应用程序对象关联的资源。 方法 Application.ShutDown 可以通过自定义代码显式调用,也可以根据属性的值 Application.ShutDownMode 在 WPF 运行时内部调用该方法。 默认情况下,对象的ShutDownModeApplication属性设置为 ShutDownMode.OnLastWindowClose. 这将导致 WPF 运行时在与该Application对象关联的最后一个 WPF 窗口关闭后自动关闭Application该对象。 在客户端应用程序已创建 WPF Application 对象的实例并显示窗口并关闭窗口的情况下,该窗口被视为最后一个窗口关闭,因此 WPF 将自动调用 Application.ShutDown