2014-08-27 2 views
5

У меня возникли трудности с отображением прогресса сборок, загружаемых в AppDomain.CurrentDomain.Как сообщить о ходе загрузки сборок в Current AppDomain в .Net на заставке?

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

Мне все равно, что сборки загружаются до отображения экрана Splash, который фактически является стандартным WPF-окном с индикатором выполнения. Когда загружен экран Splash, я хотел бы сообщить сборки, когда они загружены. Я не загружаю эти сборки вручную.

До сих пор я обработал событие запуска в App.xaml со следующей разметке:

Startup="Application_Startup" 

Соответствующий код позади для запуска выглядит следующим образом:

private void Application_Startup(object sender, StartupEventArgs e) 
{ 
SplashScreen.Show<SplashScreen>(); 
AppDomain.CurrentDomain.AssemblyLoad += CurrentDomain_AssemblyLoad; 
} 

void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args) 
{ 
    SplashScreen.CallSplashScreenMethod<SplashScreen>(x => x.Text(args.LoadedAssembly.GetName().Name)); 
} 

Это работает, как я ожидал он отображает экран всплеска и любые сборки, которые загружаются в момент отображения заставки, отображаются на экране без проблем.

splashscreen

Проблема здесь в том, что я не могу видеть способ отчетности о ходе собраний загружается.

Ассембли не кажутся загруженными линейно в любом конкретном порядке, из-за этого я не уверен, как это сделать, чтобы подсчитать оставшееся количество сборок для загрузки. Я не вижу очевидного способа, чтобы получил какие сборки в настоящее время загружается.

Если бы я мог получить список сборок еще не загружены в CLR я мог бы реализовать прогресс бар с помощью либо стандартный подсчет, вдоль линий

progress = numberOfLoadedAssemblies/totalNumberOfAssemblies * 100; 

Или путем реализации логики от Chris Marisic's excellent answer on using a weighted average

Я не могу сделать тривиальный «Directory.GetFiles(). Длина« Чтобы получить общее количество сборок для загрузки. Причина в том, что CLR не загружает сборки в каком-либо конкретном порядке. Кажется, что загружает некоторые сборки из корня приложения, затем некоторые из GAC, а затем больше из корня приложения.

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

+2

Это предполагает, что вы точно знаете, сколько времени потребуется. Конечно, нет. Вы могли бы в лучшем случае подсчитать сборки, но, тем не менее, маловероятно, чтобы они были репрезентативными, так как загрузка сборок слепо быстро. Это джиттинг и запуск кода в сборках, требующих времени. Храните то, что у вас есть. –

+0

Можете ли вы подсчитать количество раз, когда вызываются «CurrentDomain_AssemblyLoad» и обновляется ли индикатор выполнения? – Trisped

+0

@Trisped Хорошая вероятность того, что количество сборок может измениться, поскольку я добавляю дополнительные функции в свой проект. Спасибо за ваши и комментарии Ханса. –

ответ

3

Как утверждают другие, вы не можете просто предположить, что 9 сборок из 10 загруженных средств - 90%. Однако вы можете сделать эти предположения более реалистичными.

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

var totalSize = assemblies.Select(x=> x.FileSize).Sum(); 
var averageSize = totalSize/assemblies.Count(); 

var averageChange = averageSize/totalSize; 

Предположим, что ваш прогресс бар шкала от 0 до 1, вы можете просто добавить averageChange каждый раз, когда другой узел загружается.

Или вы могли бы фактически подсчитать загруженные байты и общий размер для индикатора выполнения. Я лично пошел бы с моим усредненным методом, чтобы предотвратить прогресс с [-] до [-------------------] из одной сборки. Пользователи не привыкли к нелинейным изменениям и не склонны доверять нелинейным изменениям. Предоставляя им линейно увеличивающийся индикатор выполнения, который заканчивается почти точно, когда это делается, загрузка дает людям правильное ощущение того, что все работает, и скоро будет сделано. Ошибочные скачки в шагах хода сделают пользователей чувствовать себясистема нестабильная и ненадежная.

Одна вещь, которую я не могу преуменьшить, - это то, насколько легко раздражать ваших пользователей индикатором выполнения. Ничто не раздражает пользователей больше, чем индикатор выполнения, который быстро заполняет хиты на 99% и останавливается. Это заставляет их чувствовать, что программа застыла. Им также необходимо визуальное указание, что между любой метр, что вещи не заморожены. Они также не хотят сидеть в течение долгого времени (это означает, что вы считаете секунды), посмотрите, как заполняется индикатор выполнения, а затем откидывается на ноль.

+1

Мне нравится этот ответ, я поддержал его, поскольку это хорошая идея, и подчеркивает довольно хороший момент в отношении загрузки баров в целом. Спасибо, что нашли время, чтобы написать это для меня! Это не совсем то, что мне нужно. Проблема в том, что я не могу сканировать информацию о файлах для сборок, содержащихся в GAC (Global Assembly Cache). Мне нужно знать, как получить счет всех сборок, которые нужно загрузить, файлы не обязательно все в одном каталоге, что означает, что я не могу просто выполнить тривиальную «Получить информацию о файле в каталоге« x ». Кажется, что сборки не загружены ни в каком конкретном порядке. –

+0

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

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

  • Нет связанных вопросов^_^