Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are Parking Windows in Winforms

Tags:

c#

.net

winforms

This is a follow up question to this answer https://stackoverflow.com/a/20584601/2530848.

I was under the impression that Control class doesn't implement finailzer which is true indeed, so leaked controls are leaked forever, not cleaned up during finalization.

Hans Passant gives some hint in comments section saying that it does, and some keyword ParkingWindow. I googled with that keyword, can't find any helpful resource about that.

Finally I found a class named ParkingWindow in System.Windows.Forms.Application.ParkingWindow through decompiler, I can't get to understand what is being done with that.

It looks like unparented windows will be parented to this parkingwindow and destroyed later at some point but not sure.

Question is what exactly is ParkingWindow and What it is used for?

Edit: How that is related to Control's Finalization or cleanup?

like image 672
Sriram Sakthivel Avatar asked Dec 14 '13 15:12

Sriram Sakthivel


People also ask

What is meaning of docking of controls in Winforms?

Control.Dock. Controls that are docked fill the edges of the control's container, either the form or a container control. For example, Windows Explorer docks its TreeView control to the left side of the window and its ListView control to the right side of the window.

What is Dock property in C#?

Use the Dock property to define how a control is automatically resized as its parent control is resized. For example, setting Dock to DockStyle. Left causes the control to align itself with the left edges of its parent control and to resize as the parent control is resized.


2 Answers

and destroyed later at some point but not sure

That "not sure" is the crux of the problem. This goes wrong very often with the window not getting destroyed at all.

Shawn Farka's blog post explains the original intent of the Parking Window well. The expense of having to re-create the child windows was certainly on top of the list. Not the only concern though, some types of child windows are very difficult to re-create accurately. A TreeView is a good example, there's rather a lot of runtime state associate with it. To do it accurately, you'd have to record the collapse state of every node. That's painful and Winforms does not in fact do this. When you re-assign, say, the CheckBoxes or StateImageList properties then you'll see this going wrong.

All and all, it is a nice trick but they went overboard with it. A child control doesn't just (temporarily) end up on the Parking Window when the parent window gets recreated, it also is moved there when:

  • you set its Parent property to null
  • you use the parent's Controls collection's Remove/At() method
  • you use the parent's Controls collection's Clear() method

Particularly the last two bullets are almost always deadly in a typical Winforms program. They tend to be used when the programmer dynamically adds and removes controls at runtime. Problem is, the control is re-hosted on the Parking Window but the programmer just forgets them there, losing the reference to the control. And they will live there forever. Until the user terminates the program because it turns into slow molasses from having thousands of windows created. Or the program crashes with "Error creating window handle". Which occurs when Windows gets sulky after the program has created 10,000 windows.

Instead, it is required to call the Dispose() method of the control. Very unusual in .NET in general, calling Dispose() is always optional. Not in the case of the Control class, the Parking Window keeps a reference on the control and thus prevents the finalizer from running.

like image 58
Hans Passant Avatar answered Oct 03 '22 23:10

Hans Passant


This is covered on this article by Shawn Burke from MS: Windows Forms Parking Window.

One of our goals with Windows Forms was try to smooth out as much of the oddity of Win32 as we could. And one of the principal oddities is that of window handle (HWND) management and lifetime. We certainly didn't want the average user to need to worry about this stuff. In most cases, it was pretty easy. You just gather up all of the state, and then when you actually need to show the window, you do the creation on demand, then you drive your state off the HWND instead of your internal members.

Well, this doesn't always work so well. See, there are certain properties of Win32 windows that you can't change once the window is created. Like the style of the border, for example. So to allow a user to change the border style after the window has been created, you need to recreate the handle. Which means you need to not only pull all of the state out you want out of the existing one, but you need to recreate it and push it back in. Okay, that's not too hard.

But what about the children? Oh, fiddlesticks. The kids.

If the window you're modifying the border on has children, destroying its handle will destroy the handles of all of its children as well. Then you need to recreate them, which is very expensive. And expensive is bad.

Enter the Parking Window. The Parking Window was our solution to this problem. It was somewhere that you could "park" HWNDs until you have a fitting parent for them. Think of it as Window Handle Foster Care, but invisible.

So in the case of a handle-recreate, we'd check to see if there were any children. If there were, we'd (if needed) create the Parking Window, parent the children to that, recreate the parent's handle, then move them back over. Worked pretty well, though managing the lifetime of the Parking Window did cause some problems...

like image 43
David Heffernan Avatar answered Oct 04 '22 00:10

David Heffernan