One of the great things about .NET 3.5 is that it is fully inter-operable with .NET 2.0. You just have to reference the right assemblies and you can use WPF and Windows Forms from the same application! This is great for slowly migrating a .NET 2.0 application over to .NET 3.5; all you have to do is add the new functionality while keeping your old .NET 2.0 logic. Once you are ready, you can slowly migrate your old code over into .NET 3.5 as needed.

Well...at least it's all that easy in theory; there's just one pesky little hiccup--a System.ExecutionEngineException...


What I was trying to accomplish was to create a .NET 3.0 WPF application and run a Windows Form with all of my old .NET 2.0 logic. This was easy and worked great. Then, I tried adding a WPF window which would open when a button was clicked in the Windows Form.

I compiled my application, ran it, clicked the button and the WPF window opened up just as I was hoping. Excellent! I continued working in debug mode and made some code changes. I clicked the button again to see the code changes in action and...System.ExecutionEngineException.

It took me forever to figure out what the problem was. I undid all of my code changes, I even created a blank testing application and still got the same exception.

Apparently the problem is that a .NET 3.5 WPF application has a ShutdownMode property which by default is set to "OnLastWindowClose." This means that when the last WPF Window in the application is closed, the application itself shuts down.

Oddly enough the application doesn't close the Windows Form when it "shuts down"--it just disposes of internal objects.

So this is what was happening:

  1. The application starts and shows a Windows Form.
  2. Then the Windows Form shows a WPF Window.
  3. Then the WPF Window closes and the application "shuts down" while leaving the Windows Form window open.
  4. When I try opening another WPF Window I get the exception because the application I'm trying to open a window for has already been shut down.

There are two ways to get around this problem. The first is the "right way" to do it as described in the MSDN article; it is by setting the ShutdownMode property to OnExplicitShutdown. Then to shutdown the application you could create an event handler method to be called when the Windows Form's "FormClosed" event fires. This event handler would call the applications "Shutdown()" method.

Here is an example:

App.xaml.cs

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
 
namespace MultiWindowTest
{
    ///
    /// Interaction logic for App.xaml
    ///
    public partial class App : Application
    {
 
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            Form1 f1 = new Form1();
            f1.FormClosed += new System.Windows.Forms.FormClosedEventHandler(f1_FormClosed);
            f1.ShowDialog();
        }
 
        void f1_FormClosed(object sender, System.Windows.Forms.FormClosedEventArgs e)
        {
            this.Shutdown();
        }
    }
}

An alternative way to avoid this exception is a bit of a hack; but still works. You can leave the ShutdownMode property alone and instead create a WPF window that is hidden. If you had an application that shows a splash-screen or a logon window it would make more sense to do this. The application loads, you show the logon window--once they logon this window is hidden and the Windows Form is shown. Once that form is closed you would once again show the logon WPF Window. Hiding a WPF Window does not trigger the Shutdown of the application, so you will be able to open and close as many WPF Windows as you like without worrying about getting the exception.


Rss Comment

No Comment

No comments yet.

Post a Comment





This is a captcha-picture. It is used to prevent mass-access by robots. (see: www.captcha.net)

You must read and type the 5 chars within 0..9 and A..F, and submit the form.

  

Oh no, I cannot read this. Please, generate a