No Clean Feed - Stop Internet Censorship in Australia

WPF Application hanging on exit

It turns out that you shouldn't ever construct a WPF window inside the constructor of another. If you do, the application will hang indefinitely on exit. That is, the first window will disappear, but the process will continue running.

The following code can be used to reproduce the hang:

    public partial class Window1 : Window
    {
        private Window2 window2;

        public Window1()
        {
            InitializeComponent();
            window2 = new Window2();
        }
    }

You can also see a screencast of this bug in action, courtesy Jing (I'm very pleased with Jing; I also used it to create the OBZTime screencast and wholeheartedly recommend it for quick & easy screencasts if you can handle the Jing logo at the end).

Update 14/08/2008: There's a discussion thread on this issue on MSDN Forums with details on how to solve this problem.

It turns out that I was dead wrong about the cause; it has nothing to do with the nested constructors. I was counting on the application closing when the last shown window was closed, but instead the default behaviour is to count constructed windows.

Personally I think Hua was being a little generous when he said that to have this behaviour as default is "debatable" :-)

Anyway, the fixed code looks like this:

    public partial class Window1 : Window
    {
        private Window2 window2;

        public Window1()
        {
            InitializeComponent();

            Application.Current.ShutdownMode = ShutdownMode.OnMainWindowClose;
            window2 = new Window2();
        }
    }

Constructors' constuct

Hi,

I've long found that constructor's ought only be used to construct. Even with WinForms it was real dodgy to do things in the constructor. I've often found a need to move code to the old 'Load' event handler. Recent work using NDependecnyInjection and NXmlSerializer has just enforced this. I recon, regardless of if WPF, WinForms, or just any plain 'ol class do nothing in a constructor but constuct instances.

 See ya!

Rob Smyth

Yep

I'm 100% with you on that.

The fact that we were constructing one window inside the constructor for another is related to the fact that we're not (yet) using a dependency injection framework for the application, so instantiation of objects tends to be a little, errr, ad-hoc.

If all goes according to plan we'll be incorporating Spring.NET during the next iteration. This should hopefully allow us to deal with some lifespan issues too (like knowing when to shut down WMI listeners - there's a forthcoming post about that too).