Проблема с диалоговыми окнами Open-Save под Windows 7 - PullRequest
4 голосов
/ 19 сентября 2010

Я использую Delphi 2010. Я должен установить UseLatestCommonDialogs в Ложь и дополнительно установите ofOldStyleDialog свойство диалогов Open и Save в true если я хочу, чтобы диалоги открытия и сохранения работали в Windows 7 (иначе они вообще не открываются). Также верно, что я резервирую достаточно много места для стека:

{$M 16384, 60048576}

, поскольку я использую рекурсивные алгоритмы для больших наборов данных. Теперь интересно, в чем проблема:

  1. Новые диалоги кажутся очень трудоемкими, иногда они работают в начале и после набора открывать и сохранять диалоги исполнения он больше не открывает диалоги (может быть, диалоги не освобождают память после выполнения?)

  2. Есть ли ошибка в Windows 7?

Кто-нибудь еще сталкивался с подобной проблемой?

Выглядит немного странно, работая в Windows 7 с древними диалогами. (они даже старше, чем в стиле XP, я думаю, что они похожи на Windows NT).

Любое предложение будет оценено.

Заранее спасибо.

Ответы [ 3 ]

13 голосов
/ 19 сентября 2010

Распределение стекового пространства по умолчанию, указанное $M, является глобальным для всех потоков в процессе, которые не определяют свои собственные специфические требования.Для этого достаточно 60M, гораздо больше, чем когда-либо будет расти любой стек.

Диалоги файлов по сути являются размещенной версией Windows Explorer.Они загружают расширения оболочки в ваш процесс для таких вещей, как миниатюры, обработчики столбцов, контекстные меню и т. Д. Поскольку Windows становится все более функциональной, и MS, и третьи стороны могут свободно использовать все больше ресурсов - включая потоки - для асинхронного добавления дополнительной информации,без блокировки интерфейса.Простой тест с notepad.exe на моей 64-битной машине с Windows 7 показывает, что у него 1 поток перед диалогом, но 19 потоков, пока диалог открыт.В 32-разрядном процессе с резервированием стека по умолчанию, близким к 60M, требуется резервировать более 1 ГБ или более половины общего адресного пространства, доступного для 32-разрядных приложений по умолчанию.Если в приложении вообще обрабатывается много данных, очень легко увидеть, что из-за фрагментации памяти не хватает адресного пространства - весь код из EXE, системных библиотек DLL и т. Д. Тоже должен где-то помещаться.60M - это просто слишком большое резервирование стека по умолчанию, чтобы ожидать, что оно будет работать без проблем.

Рассматривали ли вы перенос своих глубоко рекурсивных вычислений в создаваемый вами поток?Вам нужно было бы напрямую использовать BeginThread() из System, чтобы явно указать резервирование стека.

В качестве альтернативы, можно ли попытаться уменьшить использование стека вашими алгоритмами?Если вы размещаете записи или массивы в стеке, рассмотрите возможность их динамического распределения.Если у вас есть функция, которая многократно повторяется (вложена глубоко) и имеет много локальных переменных, рассмотрите возможность создания записи, содержащей локальные переменные, и ее динамического распределения.Если вы зависите от рекурсии для последовательной работы (например, обход деревьев / графов в глубину), рассмотрите возможность использования рекурсии просто для последовательной работы (например, добавьте узлы в список) и выполняйте реальную обработку итеративно.И при необходимости посмотрите на переделку алгоритма для работы с явным стеком.Другое преимущество наличия явного стека состоит в том, что при желании вы можете тривиально переключаться на ширину, используя очередь вместо стека, однострочную, если реализации стека и очереди используют полиморфный интерфейс.

0 голосов
/ 20 сентября 2010

Еще раз спасибо за этот очень точный ответ.

Я снова проверил и получил тот же результат, что вы написали: На самом деле это может быть предсказано, когда возникают проблемы с памятью:

  1. Я проверял «Состояние протектора» в Delphi 2010: при использовании старых диалоговых окон появляется новый шаг при открытии / сохранении диалогов открывается и удаляется из списка при его закрытии. Делая это с новыми диалоговыми окнами, откройте / сохраните диалоговое окно, чтобы произвести потоки, которые остановлены, но не удалены после выполнения, и что интересно: при наборе чего-либо в FileName (не выбирая файл из списка доступных файлов одним щелчком мыши) три новые темы появляются и остаются там, так что уже есть всего 9 «ненужных» тем

  2. И затем, наблюдая за диспетчером задач Windows, вы можете увидеть, что когда: "количество потоков" * "Стек, определенный в моем приложении"> «Доступная физическая память» + «Системный кэш» Программа сообщит о проблемах с памятью.

Итак, на данный момент открыто около 10 потоков и, конечно, большой стек Есть проблемы. Я проверял это только на XP, но на Windows 7, я думаю, количество генерируемые потоки еще больше?

А нет способа как-нибудь убить эту тему?

Еще раз спасибо и всего наилучшего.

"Диалоги файлов, по сути, являются размещенной версией Windows Explorer. Они загружают расширения оболочки в ваш процесс для таких вещей, как миниатюры, обработчики столбцов, контекстные меню и т. Д. По мере расширения возможностей Windows как MS, так и третьи стороны чувствуют себя свободными. использовать все больше и больше ресурсов, включая потоки, для асинхронного добавления дополнительной информации без блокировки пользовательского интерфейса. Простой тест с notepad.exe на моей 64-разрядной машине Windows 7 показывает, что перед диалогом у него 1 поток, но при этом диалоговое окно открыто. В 32-разрядном процессе с резервированием стека по умолчанию, близким к 60M, при этом требуется зарезервировать более 1 ГБ или более половины общего адресного пространства, доступного для 32-разрядных приложений по умолчанию. Если обрабатывается много данных с приложением вообще "

0 голосов
/ 19 сентября 2010

Спасибо, что вы подошли очень близко:

"Если вы зависите от рекурсии для последовательной работы (например, обход деревьев / графиков в глубину), рассмотрите возможность использования рекурсии просто для последовательности работы (например, добавлениеузлы в список) и выполнять реальную обработку итеративно. "

Да, я использую его для вычисления, например, сильно связанных компонентов графов.Я использую вариант алгоритма: http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm

И я не вижу, как это сделать без рекурсии.Есть ли у вас какие-либо предложения - или указывать на нерекурсивный алгоритм для поиска в глубине на графиках?

Best.

...