#wpf #performance #appdomain
#wpf #Производительность #appdomain
Вопрос:
У меня относительно простое приложение, Но время запуска в теплом режиме (второе и т. Д.) Ужасно 3-5 секунд. Профилировщик (VS2010, выборка процессора) показывает, что более 80% времени тратится на приложение.Запуск внутреннего (~ 40%) и XamlRader.Функции LoadBaml (~ 40%).
Корень проблемы заключается в том, что окно создается в домене приложения, отличном от стандартного. Если я перенесу создание окна в AppDomain по умолчанию или предоставлю неограниченное разрешение AppDomain, все будет так быстро, как ожидалось.
Я тестирую:
- Windows Seven x64
- .Net 4.0
- 4 ГБ оперативной памяти
- GeForce 9800GT 1 ГБ.
Я создаю AppDomain таким образом
var permissionSet = new PermissionSet(null);
permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution | SecurityPermissionFlag.SerializationFormatter | SecurityPermissionFlag.UnmanagedCode));
permissionSet.AddPermission(new ReflectionPermission(PermissionState.Unrestricted));
permissionSet.AddPermission(new UIPermission(PermissionState.Unrestricted));
permissionSet.AddPermission(new MediaPermission(PermissionState.Unrestricted));
permissionSet.AddPermission(new FileDialogPermission(PermissionState.Unrestricted));
var appDomainSetup =
new AppDomainSetup
{
ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase,
ApplicationName = AppDomain.CurrentDomain.SetupInformation.ApplicationName,
DisallowApplicationBaseProbing = false,
DisallowBindingRedirects = true,
DisallowCodeDownload = true,
DisallowPublisherPolicy = true,
LoaderOptimization = LoaderOptimization.MultiDomainHost
};
_appDomain =
AppDomain.CreateDomain(
name,
null,
appDomainSetup,
permissionSet,
new[]
{
// a few types I need
typeof(...).Assembly.Evidence.GetHostEvidence<StrongName>(),
});
Поведение остается прежним, даже если я отключаю XAML до пустого окна
<Window
x:Class="Rosmurta.Extensibility.WpfUI.RosmurtaWindow"
x:ClassModifier="internal"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test"
Height="480"
Width="640"
WindowStyle="SingleBorderWindow">
<Grid>
</Grid>
</Window>
Не слишком много для анализа с помощью XamlRader.LoadBaml, но он тратит более 30% времени запуска события на пустое окно.
Я пробовал (и это не помогло)
- Добавление <generatePublisherEvidence включено=»false»/> в App.config .
- Добавление [Оптимизация загрузки (LoaderOptimization.Многодоменный хост)] приписывается основному методу.
- Добавление подписей ко всем сборкам.
Что еще можно сделать?
Комментарии:
1. Привет, как насчет перехода к фактическим вызовам?
2. @Dmitry, это методы в PresentationFramework.dll . Даже если я каким-то образом войду в них, я не смогу их профилировать.
3. сложно, но вы не можете нанять Роба Рели, не так ли?:) даже тогда — первый вопрос, который он задаст, — зачем вам загружать ваше приложение в отдельный домен приложения?:) Задержка «3-5 секунд» должна быть достаточно ощутимой, чтобы уловить причину при отладке, которую нужноя, похоже, единственный жизнеспособный вариант.
4. Ответ прост, безопасность. Как вы можете видеть из предоставленного мной исходного кода, применяются некоторые ограничения CAS. Чего я не могу понять, так это того, что нет исключений первого шанса или каких-либо других признаков проблемы, код просто работает медленнее в ограниченном домене. В неограниченном домене, отличном от домена по умолчанию, все происходит быстро, поэтому CAS является причиной, прямо или косвенно. Я буду продолжать пытаться отладить это, просто подумал, что у кого-то может быть ответ.
5. итак, вы говорите, что не можете решить проблему, просто загрузив свое приложение в отдельный домен приложения? существует ли конкретная настройка CAS, которая плохо влияет на производительность? — зная это, вы можете войти в .net-код и посмотреть, что там происходит. извините за общий ответ, но это единственный способ, который я вижу.
Ответ №1:
Вопрос очень старый, но, вероятно, мой ответ кому-нибудь поможет. Иногда XamlReader определенно занимает много времени во время запуска, однако это не всегда означает, что проблема вызвана самим синтаксическим анализом. Когда анализируется XAML, XAMLParser выполняет несколько относительно сложных операций, за исключением синтаксического анализа:
- Использует отражение для получения неизвестных типов и экземпляров ящиков
- Инициализирует объекты и создает экземпляры. Если ваш XAML (или XAML используемой библиотеки компонентов) содержит много пользовательских классов, они создаются XAMLParser и происходит jitting.
- Выполняет поиск ресурсов в иерархии словаря ресурсов и более того. Если иерархия словарей ресурсов действительно сложная, эта операция займет некоторое время.
Существует несколько общих методов, которые могут помочь вам сократить время запуска приложения WPF:
- Создайте собственные изображения с помощью инструмента Ngen.
- Включить многоядерный JIT, когда Ngen не применим
- Используйте ReadyToRun в сочетании с многоядерным JIT для проектов .NET Core, поскольку для них нет Ngen
- Загружайте данные по требованию. Я думаю, что это не ваш случай, но может быть полезно для полной картины. Например, DevExpress имеет функции виртуального исходного кода и режима сервера, чтобы сделать это асинхронно для вас.
- Вы также можете обернуть «тяжелые» представления в элементы управления, которые задерживают их загрузку, не замораживая пользовательский интерфейс. Например, вы можете использовать DevExpress LoadingDecorator
- Убедитесь, что ваши элементы управления представлением не расширены за пределы видимой области. Например, если у вас есть StackPanel с ListBox внутри, ListBox создаст все свои элементы одновременно, потому что StackPanel не ограничивает высоту для своих дочерних элементов, и они «думают», что у них бесконечная высота. В результате ListBox создаст все визуальные элементы сразу и значительно снизит вашу производительность.
- В качестве простого способа определения узких мест вы можете прокомментировать пользовательский интерфейс, вы можете прокомментировать наши части XAML и посмотреть, как это влияет на запуск
Вот сообщение в блоге, которое может быть полезным: 9 советов по сокращению времени запуска приложения WPF