Время запуска приложения
Время, необходимое для запуска WPF-приложения, может сильно варьироваться. В этом разделе описаны различные способы, позволяющие сократить воспринимаемое и фактическое время запуска приложений Windows Presentation Foundation (WPF).
Общее представление о холодном и горячем запуске
Холодный запуск происходит, когда вы запускаете приложение в первый раз после перезагрузки системы либо когда вы запускаете приложение, закрываете его и запускаете снова после длительного периода времени. Если при запуске приложения в списке ожидания диспетчера памяти WIndows не окажется необходимых страниц (кода, статических данных, реестра и т. д.), возникнет ошибка страницы. Для загрузки таких страниц в память требуется доступ к диску.
Горячий запуск происходит, когда большинство страниц для основных компонентов среды CLR уже загружены в память, что экономит дорогостоящее время доступа к диску. Вот почему при повторном запуске управляемое приложение запускается быстрее.
Реализация экрана-заставки
В случаях когда между запуском приложения и отображением первого графического интерфейса происходит значительная неизбежная задержка, можно оптимизировать воспринимаемое время запуска с помощью экрана-заставки. В этом случае изображение появляется практически сразу после того, как пользователь запустит приложение. Когда приложение будет готово к отображению первого пользовательского интерфейса, экран-заставка исчезнет. Начиная с версии .NET Framework 3.5 SP1, можно использовать SplashScreen класс для реализации экрана-заставки. Дополнительные сведения см. в разделе Практическое руководство. Добавление в WPF-приложение экрана-заставки.
Кроме того, используя собственные графические средства Win32, вы можете реализовать свой собственный экран заставки. Отобразите реализацию перед Run вызывается метод.
Анализ кода запуска
Определите причину задержки холодного запуска. Она может быть связана с дисковым вводом-выводом, но необязательно. В целом использование внешних ресурсов, таких как сеть, веб-службы или диск, следует минимизировать.
Перед проверкой убедитесь, что управляемый или WPF-код не используют другие выполняемые приложения.
Сразу после перезагрузки перезапустите WPF-приложение и определите, сколько времени занимает его отображение. Если последующие запуски приложения (горячий запуск) будут происходить быстрее, то проблема холодного запуска, скорее всего, была связана с вводом-выводом.
Если проблема холодного запуска не связана с вводом-выводом, возможно, ваше приложение выполняет какую-либо длительную инициализацию или вычисление, ожидает завершения какого-либо события или требует существенной JIT-компиляции при запуске. В следующих разделах эти ситуации описываются более подробно.
Оптимизация загрузки модулей
Чтобы определить, какие модули загружает ваше приложение, воспользуйтесь такими средствами, как обозреватель процессов (Procexp.exe) и Tlist.exe. Команда Tlist <pid>
показывает все модули, загруженные процессом.
Например, если вы не подключаетесь к Интернету, но видите, что загружается процесс System.Web.dll, значит, в приложение есть модуль, который ссылается на эту сборку. Убедитесь, что эта ссылка действительно необходима.
Если в приложении несколько модулей, объедините их в один. В этом случае загрузка сборок CLR займет меньше времени. Меньшее количество сборок также означает, что в CLR хранится меньше состояний.
Приостановка операций инициализации
Код инициализации можно отложить до тех пор, пока обработка основного окна приложения не будет завершена.
Помните, что инициализация может выполняться в конструкторе классов, а в случае если код инициализации ссылается на другие классы, это может привести к каскадному выполнению многих конструкторов классов.
Предотвращение конфигурации приложения
Конфигурации приложения можно избежать. Например, если приложение имеет простые требования к конфигурации и строгое плановое время запуска, для запуска лучше использовать записи реестров или простой INI-файл.
Использование GAC
Если сборка не установлена в глобальном кэше сборок (GAC), возникают задержки, связанные с проверкой хэша сборок со строгими именами, а также с проверкой образа Ngen (если на компьютере доступен машинный образ для этой сборки). Для всех сборок, установленных в GAC, проверка строгих имен пропускается. Дополнительные сведения см. в разделе Gacutil.exe (средство глобального кэша сборок).
Применение Ngen.exe
В приложении можно использовать генератор образов в машинном коде (Ngen.exe). При использовании Ngen.exe вы меняете потребление ресурсов ЦП на улучшение доступа к диску, поскольку машинный образ, созданный Ngen.exe, скорее всего, будет больше, чем образ MSIL.
Чтобы сократить время горячего запуска, всегда используйте Ngen.exe в своем приложении, поскольку при этом JIT-компиляция кода приложения не влияет на потребление ресурсов ЦП.
Ngen.exe может также пригодиться в некоторых сценариях холодного запуска, поскольку в этом случае загрузка JIT-компилятора (mscorjit.dll) не требуется.
Одновременное присутствие модулей Ngen и JIT может вызвать противоположный эффект. Это связано с тем, что при этом требуется загрузка mscorjit.dll, а когда JIT-компилятор работает с вашим кодом и считывает метаданные сборок, происходит обращение к многим страницам в образах Ngen.
NGen и ClickOnce
Время загрузки вашего приложения может также зависеть от выбранного способа его развертывания. ClickOnce развертывание приложений не поддерживает Ngen. Если вы решите использовать Ngen.exe для своего приложения, выберите другой механизм развертывания, например установщик Windows.
См. дополнительные сведения о файле Ngen.exe (генераторе образов в машинном коде).
Изменение базового адреса и конфликты DLL-адресов
При использовании Ngen.exe следует учитывать, что при загрузке машинных образов в память может измениться базовый адрес. Если DLL не загружается по предпочтительному базовому адресу, поскольку этот диапазон адресов уже распределен, загрузчик Windows загрузит файл по другому адресу, что может потребовать много времени.
Проверить наличие модулей, в которых все страницы являются закрытыми, можно с помощью средства Virtual Address Dump (Vadump.exe). Если такой модуль имеется, его адрес может измениться. После этого его страницы станут недоступны.
Дополнительные сведения о настройке базового адреса см. в разделе Ngen.exe (генератор образов в машинном коде).
Оптимизация Authenticode
Проверка Authenticode увеличивает время запуска. Сборки, подписанные с помощью Authenticode, должны проверяться центром сертификации (ЦС). Такая проверка может занять много времени, поскольку требует многократного подключения к сети для загрузки текущих списков отзыва сертификатов. Она также обеспечивает всю цепочку действительных сертификатов на пути к доверенному корневому центру. В результате загрузка сборки может задержаться на несколько секунд.
Вы можете установить сертификат CA на клиентский компьютер или не использовать Authenticode, когда это возможно. Если вашему приложению не требуется свидетельство издателя, платить за проверку подписи вам не нужно.
Начиная с версии .NET Framework 3,5, конфигурация включает параметр, позволяющий отключить проверку Authenticode. Для этого добавьте в файл конфигурации app.exe следующий параметр.
<configuration>
<runtime>
<generatePublisherEvidence enabled="false"/>
</runtime>
</configuration>
Дополнительные сведения см. в разделе <Элемент generatePublisherEvidence>.
Сравнение производительности в Windows Vista
Диспетчер памяти в Windows Vista включает технологию, которая называется SuperFetch. SuperFetch анализирует шаблоны использования памяти с течением времени, определяя оптимальное содержимое памяти для конкретного пользователя. Она работает постоянно, поддерживая содержимое памяти в любой момент времени.
Этот подход отличается от технологии Windows XP, которая выполняет предварительную загрузку данных в память без анализа шаблонов использования. Если пользователь часто работает с вашим приложением WPF в Windows Vista, время холодного запуска вашего приложения может сократиться.
Эффективное использование доменов приложения
По возможности загружайте сборки в область кода с нейтральным доменом, чтобы машинный образ, если таковой существует, использовался во всех созданных в приложении доменах.
Чтобы повысить производительность, необходимо обеспечить взаимодействие между доменами, сократив число междоменных вызовов. По возможности используйте вызовы без аргументов или с аргументами примитивного типа.
Использование атрибута NeutralResourcesLanguage
Используйте NeutralResourcesLanguageAttribute для указания нейтрального языка и региональных параметров для ResourceManager. Этот подход позволяет избежать неудачного поиска сборок.
Использование класса BinaryFormatter для сериализации
Если необходимо использовать сериализацию, используйте BinaryFormatter вместо класса XmlSerializer класса. BinaryFormatter Класс реализован в библиотеке базовых классов (BCL) в сборке mscorlib.dll. XmlSerializer Реализуется в сборке System.Xml.dll, что может быть загрузку дополнительного DLL.
Если необходимо использовать XmlSerializer класс, вы может повысить производительность, можно создать предварительную сборку сериализации.
Настройка технологии ClickOnce на проверку обновлений после запуска
Если приложение использует ClickOnce, запретите подключение к сети при запуске, настроив ClickOnce на проверку наличия обновлений на сайте развертывания после запуска приложения.
Если используется модель приложения браузера XAML (XBAP), обратите внимание на то, что ClickOnce проверяет наличие обновлений на сайте развертывания, даже если XBAP уже присутствует в кэше ClickOnce. Для получения дополнительной информации см. ClickOnce Security and Deployment.
Настройка автоматического запуска службы PresentationFontCache
Первым WPF-приложением, которое загружается после перезагрузки, является служба PresentationFontCache. Служба кэширует системные шрифты, делает их более доступными и повышает общую производительность. Поскольку с запуском службы, а также с некоторыми управляемыми средами связаны временные задержки, службу можно настроить на автоматический запуск при перезагрузке системы.
Настройка программной привязки данных
Вместо использования XAML для задания DataContext декларативно для главного окна, рассмотрите возможность установки его в обработчике OnActivated метод.