System.ExecutionEngineException se produce al mostrar la ventana de WPF

Este artículo le ayuda a resolver el problema en el que al intentar crear una instancia de otra ventana de WPF se produce una excepción no controlada después de cerrar una ventana de Windows Presentation Foundation (WPF).

Versión original del producto: Visual Studio Professional 2010
Número de KB original: 2691806

Síntoma

Ha desarrollado un componente WPF de Microsoft .NET 3.5 y lo ha hospedado en una aplicación cliente no basada en WPF, como una aplicación de Windows Forms o una aplicación nativa. La aplicación cliente llama al componente WPF para crear instancias y mostrar una ventana de WPF personalizada. La primera creación de instancias de Windows se muestra como se esperaba. Sin embargo, después de cerrar la ventana e intentar crear una instancia de otra ventana de WPF da como resultado una excepción no controlada.

Si ejecuta la aplicación en el IDE de Visual Studio, recibirá la siguiente excepción y pila de llamadas:

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)

Si ejecuta la aplicación en un depurador nativo, como Windbg, recibirá una excepción de punto de interrupción con la siguiente pila de llamadas.

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! DepurarBreak+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

Causa

El síntoma del bloqueo se produce cuando la aplicación llama al System.Windows.Application.LoadComponent método para cargar un archivo XAML, asociado a una ventana de WPF o UserControl. Finalmente, el tiempo de ejecución de WPF llama a System.Windows.Application.GetResourceOrContentPart para cargar paquetes de recursos asociados al objeto actual System.Windows.Application .

Este error se produce porque no se pudieron recuperar los paquetes de recursos asociados al objeto actual System.Windows.Application . Esto suele ocurrir porque el objeto actual System.Windows.Application ya se ha cerrado, ya sea mediante una llamada explícita o implícita a Application.ShutDown.

Este comportamiento es por diseño.

Resolución

Al crear la instancia del System.Windows.Application objeto, establezca su ShutDownMode propiedad ShutDownMode.OnExplicitShutdownen . Esto solo permitirá que el Application objeto se apague como resultado de una llamada explícita de código personalizado a Application.ShutDown.

Información adicional

Cuando se llama al Application.ShutDown método , el tiempo de ejecución de WPF descarga los paquetes de recursos asociados a ese Application objeto. En algún momento más adelante, si la aplicación hace algo que requiere tener acceso a los recursos asociados con el mismo Application objeto, el System.Windows.Application.GetResourceOrContentPart método intenta cargar esos paquetes de recursos, pero no puede porque se descargaron anteriormente. Cuando WPF detecta esto, se considera una condición irrecuperable y WPF llama intencionadamente a System.Environment.FailFast, que produce y System.ExecutionEngineException finaliza el proceso.

Una aplicación cliente puede crear una instancia de un System.Windows.Application tipo (o derivado) por AppDomain. Los recursos asociados a ese objeto Application se descargan cuando se llama al Application.ShutDown método . El Application.ShutDown código personalizado puede llamar al método explícitamente o el tiempo de ejecución de WPF puede llamarlo internamente en función del valor de la Application.ShutDownMode propiedad . De forma predeterminada, la ShutDownMode propiedad del Application objeto se establece en ShutDownMode.OnLastWindowClose. Esto hará que el tiempo de ejecución de WPF apague el Application objeto automáticamente después de que se haya cerrado la última ventana de WPF asociada a ese Application objeto. En un escenario en el que una aplicación cliente ha creado una instancia de un objeto WPF Application y ha mostrado una ventana y la ha cerrado, esa ventana se considera la última ventana cerrada, por lo que WPF llamará automáticamente a Application.ShutDown.