2013-12-14 2 views
6

Это следующий вопрос к этому вопросу https://stackoverflow.com/a/20584601/2530848.Что такое «Окна парковки в Winforms»

У меня создалось впечатление, что класс Control не реализует finailzer, который действительно правдивый, поэтому просочившиеся элементы управления просачиваются навсегда, а не очищаются во время финализации.

Hans Passant дает некоторый намек в разделе комментариев, говорящих, что это так, и некоторое ключевое слово ParkingWindow. Я googled с этим ключевым словом, не могу найти полезный ресурс об этом.

Наконец-то я нашел класс с именем ParkingWindow в System.Windows.Forms.Application.ParkingWindow через декомпилятор, я не могу понять, что с ним делается.

Похоже, что неэкранированные окна будут отпечатаны на этом парковочном окошке и впоследствии уничтожены, но не уверены.

Вопрос в том, что именно есть ParkingWindow и для чего он используется?

Редактировать: Как это связано с завершением или очисткой Control?

+0

См. Http://stackoverflow.com/a/4083415/76337 –

ответ

8

и уничтожены позже в какой-то момент, но не уверен, что

что «не уверен» является суть проблемы. Это происходит не так часто, когда окно не разрушается вообще.

В блоге Shawn Farka объясняется первоначальное намерение окна парковки хорошо. Затраты на повторное создание дочерних окон были, безусловно, выше списка. Не единственное беспокойство, хотя некоторые типы дочерних окон очень трудно воссоздать точно. Хороший пример - TreeView, с ним связано довольно много состояний среды выполнения. Чтобы сделать это точно, вам нужно записать состояние срыва каждого узла. Это больно, и Winforms на самом деле этого не делают. Когда вы повторно назначаете, скажем, объекты CheckBoxes или StateImageList, вы увидите, что это происходит неправильно.

Все и все, это хороший трюк, но они пошли за борт с ним. Контрольный ребенок не только (временно) в конечный итоге на автостоянку окне, когда родительское окно пересоздалось, он также перемещается туда, когда:

  • вы установите его свойство Parent обнулить
  • вы используете родитель Удалить коллекцию элементов управления в метод
  • /в() используется метод Controls коллекции родительского объекта в Clear()

Особенно последние две пули почти всегда смертельной в типичной программе Winforms. Они, как правило, используются, когда программист динамически добавляет и удаляет элементы управления во время выполнения. Проблема в том, что элемент управления снова размещен в окне парковки, но программист просто забыл их там, потеряв ссылку на элемент управления. И они будут жить там forever. До тех пор, пока пользователь не завершит программу, потому что она превращается в медленную мелассу из создания тысяч окон. Или программа вылетает с «Ошибка создания дескриптора окна». Что происходит, когда Windows становится тупой после того, как программа создала 10 000 окон.

Вместо этого требуется, чтобы вызвать метод Dispose() элемента управления. Очень необычно в .NET в целом, вызов Dispose() всегда является необязательным. Не в случае класса Control, окно парковки сохраняет ссылку на элемент управления и, таким образом, предотвращает запуск финализатора.

+0

Повторное создание окон сложно, и это то, что дизайнеры VCL, вероятно, ошибались. Там элементы управления сохраняют свое состояние и пытаются восстановить его. Я думаю, что пользователи WinForms узнали о опыте VCL. –

+0

Непонятно, что это * Окно парковки содержит ссылку на элемент управления и, таким образом, предотвращает запуск финализатора * Я не вижу, что класс управления реализует деструктор. Что вы подразумеваете под финализатором здесь? –

+0

Финализатор находится в базовом классе, Component.Он реализует одноразовый шаблон, поэтому Dispose (bool) - это тот, который выполняется. Там также есть сантехника в NativeWindow, которая завернута. Это ... свернуто. –

7

Это статья этой статьи Шона Берка от MS: Windows Forms Parking Window.

Одна из наших целей с Windows Forms заключалась в том, чтобы сгладить как можно больше странность Win32. И одна из главных странностей - - управление и управление окном (HWND). Мы, конечно, не хотели, чтобы средний пользователь беспокоился об этом. В большинстве случаев это было довольно легко. Вы просто собираете все состояние, , а затем, когда вам действительно нужно отобразить окно, вы создаете создание по запросу, затем вы управляете своим состоянием из HWND вместо ваших внутренних членов.

Ну, это не всегда так хорошо работает. См., Есть определенные свойства окон Win32, которые вы не можете изменить после создания окна . Например, стиль границы. Таким образом, чтобы пользователь изменил стиль границы после создания окна, вам необходимо восстановить дескриптор. . Это означает, что вам нужно не только вытащить все из состояния, которое вы хотите, из существующего, но вам нужно, чтобы воссоздать его и вставить обратно. Ладно, это не слишком сложно.

А как же дети? О, фехтование. Дети.

Если в окне, которое вы изменяете на границе, есть дети, уничтожая , его дескриптор также уничтожит ручки всех своих детей. Тогда вам нужно воссоздать их, что очень дорого. И дорогоплохо.

Войдите в окно парковки. Окно парковки было нашим решением этой проблемы . Это было где-то, что вы могли бы «припарковать» HWND, пока у вас не будет подходящего родителя для них. Подумайте об этом как Охотничьей ручке, , но невидимой.

Так что в случае ручного воссоздания мы проверили бы, есть ли у любые дети.Если бы это было так, мы бы (при необходимости) создали парковку Окно, родив дочерние элементы для этого, заново создайте дескриптор родителя, , затем переместите их обратно. Работали очень хорошо, хотя управление срок службы парковки Окно было вызвать некоторые проблемы ...

+2

Спасибо, Дэвид. Очень интересная статья –

+0

Не могли бы вы рассказать о том, как это связано с завершением Контроля, как сказал Ганс? Мне здесь не хватает. –

+0

Это другой вопрос. Я ничего не знаю об этом. Вы только что спросили: «Что такое« ParkingWindow »и для чего он используется? * –

Смежные вопросы