Почему пытается открыть TOpenDialog, порождающий тонну потоков?

У меня есть очень простая форма с TOpenDialog и кнопкой. Когда я нажимаю кнопку, он вызывает Выполнить в диалоговом окне. Если я смотрю в отладчике, процесс открытия диалогового окна порождает что-то вроде 14 потоков, и они не исчезают, когда я закрываю диалоговое окно.

Кто-нибудь знает, что с этим происходит?

1 ответ

Решение

Представьте, что вы хотите показать своим друзьям, как прекрасен Тихоокеанский Северо-Запад. Вы решили отправиться в путешествие, чтобы сделать несколько фотографий заката над Тихим океаном. Что вас действительно волнует, так это файлы изображений, возвращающиеся домой, где они могут быть загружены на Facebook. На самом деле камеру, объективы и штатив нужно тащить над Олимпиадой и обратно. Вы также должны привести фотографа (себя), который настроит камеру и нажмет кнопку затвора. Фотограф должен перемещаться туда и обратно в относительном комфорте, поэтому вы садитесь на место, на котором фотограф будет отдыхать во время поездки. Это сиденье заключено в блестящую металлическую коробку с кучей других металлических, стеклянных и резиновых деталей, некоторые из которых вращаются и совершают возвратно-поступательное движение. В конце концов, около двух тонн вещей (и живого человека) совершают многочасовое путешествие, сжигая галлоны углеводородной жидкости - с целью передачи нескольких кусочков информации с берега в Интернет.

Точно то же самое происходит с вашим приложением. Когда пользователь хочет открыть файл с помощью диалогового окна "Открыть файл", он ожидает, что сможет:

  • перейти к каталогу, содержащему файл (каталог может находиться на локальном жестком диске или CD/DVD/BR, или на сетевом диске, или в архиве и т. д. Носитель может быть зашифрован или сжат, что должно отображаться по-разному. подключен, для чего пользователю может потребоваться запрос. Носитель может потребовать учетные данные пользователя, которые должны быть запрошены);
  • подключиться к новому каталогу, используя его URI/UNC (сопоставить диск);
  • поиск в каталоге по ключевым словам;
  • копировать / удалять / переименовывать некоторые файлы;
  • увидеть список файлов в этом каталоге;
  • предварительный просмотр содержимого каждого файла в каталоге;
  • выберите, какой файл открыть;
  • передумали и решили не открывать файл;
  • делать много других вещей, связанных с файлами.

ОС позволяет всему этому происходить, предоставляя вашему процессу большую часть функциональности Windows Explorer. И некоторые из них должны происходить в фоновом режиме, в противном случае пользователи будут жаловаться на то, как не отвечает диалог открытия файла. Очевидный способ запустить некоторые задачи в фоновом режиме - запустить их в разных потоках. Так вот что мы видим.

Вы спросите, что насчет оставленных тем? Ну, некоторые из них оставлены там для случая, когда пользователь решит открыть другой файл: это экономит много времени, трафика и печатает в этом случае. Эта пользовательская аутентификация использовалась для этого конкретного процесса в прошлый раз? - хранится Иконки предварительного просмотра для этих надоедливых PDF-файлов? -- все еще там. Длина и битрейт для каждого фильма в каталоге? - по-прежнему в наличии, не нужно их повторно анализировать.

Конечно, темы не просто волшебным образом появляются сами по себе. Проверьте, сколько DLL было сопоставлено с процессом. Глядя на некоторые из них, можно получить довольно интересную картину того, какие функции были добавлены.

Еще один интересный способ посмотреть на это - сбросить стеки вызовов в момент создания каждого потока. Это показывает, какая DLL (а иногда и какой объект) создал их. Вот как x7 Win7 создает все потоки. Можно найти созданный поток фрейма Explorer; некоторые действия OLE, которые будут использоваться для создания экземпляров файловых фильтров, некоторые из которых могут генерировать значки предварительного просмотра, наложения и всплывающие подсказки; несколько потоков, принадлежащих поисковой подсистеме; перечислитель устройства оболочки (поэтому, если пользователь подключит новое устройство, оно автоматически появится в открытом диалоговом окне); оболочка сетевого монитора (тоже) и прочее.

Хорошей новостью является то, что это происходит быстро и не добавляет слишком много накладных расходов вашему процессу. Большинство потоков тратят большую часть времени в ожидании некоторых редко встречающихся событий (например, при подключении USB-ключа), поэтому процессор не тратит время на их выполнение. Каждый поток потребляет 1 МБ виртуального адресного пространства в вашем процессе, но только несколько страниц по 4 КБ физической памяти. И большинство, если не все эти библиотеки DLL не использовали какую-либо полосу пропускания диска для загрузки: они уже были в оперативной памяти, поэтому они просто были подключены к вашему процессу практически бесплатно.

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

Другие вопросы по тегам