Blog - Title

The first of many performance discoveries

The first of many performance discoveries

Rate This
  • Comments 26

Along with painting the big picture of our performance efforts I'd like to share a few specific things we've learned along the way.  The first is hosting a WPF window inside a Windows Forms Window.

We've spent a lot of time looking at memory usage over the past several months and one of the things that we saw was that some tool windows were causing surprising growth in memory usage.  We tracked the problem down to hosting a WPF control inside a WinForms window wrapper.  I'm particularly close to this one because the issue was discovered by the TFS team.  We've done some cool visualizations in this release (like branch hierarchy and merge visualization, etc) and we chose to use WPF to create them to get really nice looking images.  We found that we had 3 tool windows in version control alone that used this.  I know there are others.  Once we shared the learning with the rest of the division, I heard anecdotal reports from other areas of the product but I never did a full tally.

The situation is this...

WPF can not render natively into a Windows Forms window.  Instead it renders into memory and "bitblts" it into the WinForms window.  We observed that, in our VS tool windows, there was about a 20MB memory cost for each tool window to do this.  Further we saw transient incremental memory allocation as the tool windows were resized of about 4MB per resize (although it was garbage and the GC would eventually reclaim it).

We have solved the problem by eliminating the intermediate WinForms wrapper windows in the WPF tool window chain (VS now provides a native WPF root level tool window).

This change has saved dozens of megabytes in some VS scenarios and is something you should be thoughtful about as you look at extending Windows Forms applications with new WPF components.

Brian

Leave a Comment
  • Please add 6 and 7 and type the answer here:
  • Post
  • "WPF can not render natively into a Windows Forms window. "

    Interesting. Does this apply only to WinForms windows or to any Win32 based window? After all WinForms is just a wrapper around Win32.

    While I'm here I'll say that beta 2 works reasonably well for me. Except the XAML editor! It's slow to open, slow to close, sometimes freezes etc. I'd be curious what's going in there.

  • Awesome anecdote!  Lovin' the transparency you're providing Brian!  And THANK YOU for not sugar-coating this stuff.  Great appreciation for all the effort going into the perf. issues with VS 2010, and looking forward to the next release.

  • While I'm here I'll say that beta 2 works reasonably well for me. Except the XAML editor! It's slow to open, slow to close, sometimes freezes etc. I'd be curious what's going in there.

  • Mike,

    Have you tried the following registry change to see if it improves XAML editor performance:

    http://social.msdn.microsoft.com/Forums/en-US/vswpfdesigner/thread/4511d43f-c134-4329-a970-e374252a620e

    Regards,

    David Berg

    Microsoft Developer Division Performance Engineering

  • Yes, I tried that. It seems to improve things a bit but I'm still seeing freezes. For example:

    - Open a small WPF project (TreeListView sample from MSDN in particular but I don't think this is relevant).

    - Open a .cs file. CPU Time used = ~1sec

    - Close and open the .cs file again. It's almost instant.

    - Restart VS with the same project

    - Open an .xaml file. CPU Time used = ~20 sec!!

    - Close and open the .xaml file again. Sometimes this is fast (like for a .cs file) but sometimes it freezes for a couple of seconds.

  • I knew the Win32 question would come up and I should have just answered it in the first post :)  A little color on the issue.  It has to do with how transparency is supported when WPF is composed on a Windows Forms form.  The current implementation takes the conservative route and uses a more complex compositing technique even when there is no transparency involved.

    The overly conservative code only comes into play when WinForms is hosting a WPF control and not on other Win32 based windows.  I suspect, in the future, we'll look at modifications to only incur the overhead when it is really necessary.  In the mean time, it's something to be careful about.

    Brian

  • Do you know if this is going to be fixed in the next .NET 4 release? Or should we minimize hosting WPF controls in WinForms applications?

  • To my knowledge, it will not be changed for .NET 4.  You should be thoughtful about hosting a WPF control in a Windows Forms form.  The memory overhead is not so onerous that I'd say you should never do it but if you do it a lot or you have other memory issues already, it may be a bigger problem for you.

    Brian

  • Hi Brian,

    I'm currently working on a VS2010 plugin with several tool windows and a custom editor myself.

    Is the "native" WPF toolwindow already part of beta 2? If so, how can I use it in my own VS package? I'm still using ElementHost to host my WPF contents in the tool windows and editors.

    Thanks,

    Mathias

  • @Mathias,

    Yes, native WPF toolwindow and editor hosting is available in Beta 2. In fact, this is the default for code generated by the “Visual Studio Integration Package” wizard in the Beta 2 SDK.

    Visit the Visual Studio Extensibility forum if you have further questions about it.

    Beta 2 SDK download:

    http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=cb82d35c-1632-4370-acfb-83c01c2ece24

    Visual Studio Extensibility forum:

    http://social.msdn.microsoft.com/Forums/en-US/vsxprerelease/threads

  • Yes. The WPF tool window support was in Beta 2. In a nutshell, you’ll need to rip out the WinForms code that contains ElementHost and replace it with a WPF container control like UserControl. Additionally, instead of overriding the Window property in the WindowPane (or ToolWindowPane), you need to override the Content property and return a reference to your WPF container.

    -Tan

  • I know this marks me out as an old git, but does anyone look at that 20MB per bitblt'd tool window and ask why it's 20MB?

    What can possibly be in there that takes so much memory, and why's it needing the memory for any longer than it takes to render the image and blit it?    That sounds like the 4M which is used transiently on a resize - so what's the rest?

    Wouldn't it be better to send Rico with his chainsaw/flamethrower to the WPF group to get this sorted properly, rather than just ducking it by avoiding your own group falling into this trap?  

    "To my knowledge, it will not be changed for .NET 4." isn't very reassuring - if the WPF team can't be made to fix this for VS, they're never going to fix it for the rest of us.

  • It does seem high and there's an active discussion going on internally (sparked by my post :)) about why it's that high and is it really that high?, etc.  Discussions have revealed that the size is compounded by "Sandwiching".  The outermost tool window is WPF, it's hosting a WinForms window, which is hosting a WPF window.  This compounds the memory overhead.

    I started a conversation with the WPF team earlier today to confirm they don't plan to change this behavior, but I don't think so.  I agree it would be nice if they could but for us, and I suspect for most people, it's not unworkable.  There are places where we still cross host WPF and WinForms and it's not unacceptable.  It's just a cost you need to be aware of.

    Brian

  • Hmm, it turns out that the WPF designer and XAML editor are hosted inside a WinForms control (or more exactly 3-4 nested WinForms controls). Maybe that's why sometimes the XAML editor flashes :)

  • I wonder whether this will also solve the very slow resize issue I reported. The affected tool windows were:

    Output - No

    Immediate - No

    Call Stack - Yes

    Locals - Yes

    Modules - No

    Autos - Yes

    Threads - No

    Processes - No

    Error List - No

    Registers - Yes

    Watch - Yes

Page 1 of 2 (26 items) 12