Я реализовал простое окно экрана-заставки WPF, которое сообщает пользователю о прогрессе запуска приложения.
Шаги запуска определяются этот путь:
var bootSequence =
new[]
{
new {Do = (Action) InitLogging, Message = "Init logging..."},
new {Do = (Action) InitNHibernate, Message = "Init NHibernate..."},
new {Do = (Action) SetupUnityContainer, Message = "Init Unity..."},
new {Do = (Action) UserLogOn, Message = "Logon..."},
new {Do = (Action) PrefetchData, Message = "Caching..."},
};
InitLogging
и т.д. методы, определенные в другом месте, который выполняет некоторые трудоемкие задачи.
Последовательность начальной загрузки выполняется этот путь:
foreach (var step in bootSequence)
{
_status.Update(step.Message);
step.Do();
}
_status
обозначает экземпляр моего окна экрана-заставки XAML, содержащего индикатор выполнения и маркировку для получения информации о статусе. Update()
метод определяется следующим образом:
public void Update(string status)
{
int value = ++_updateSteps;
Update(status, value);
}
private void Update(string status, int value)
{
var dispatcherOperation = Dispatcher.BeginInvoke(
DispatcherPriority.Background,
(ThreadStart) delegate
{
lblStatus.Content = status;
progressBar.Value = value;
});
dispatcherOperation.Wait();
}
В основном это работает, шаги выполняются, и экран-заставка показывает прогресс. Но я заметил, что экран-заставка по некоторым причинам не обновляет свое содержание для всех шагов. Это - причина, я назвал Диспетчера асинхронным, и ожидайте ее завершения. Но даже это не помогло.
Кто-либо еще испытал это или некоторое подобное поведение и имеет некоторый совет, как сохранить обновление экрана-заставки в синхронизации с выполнением шагов последовательности начальной загрузки? Я знаю, что пользователи вряд ли заметят это поведение, так как экран-заставка делает что-то, и приложение запускается после того, как начальная загрузка завершается. Но я не спит хорошо, потому что я не знаю, почему это не работает как ожидалось...
Спасибо за Вашу справку, Denny
Наконец, я нашел простое решение своей проблемы: я выполняю трудоемкие шаги запуска в фоновом работнике! Это вернуло потоку пользовательского интерфейса отзывчивость ...
Я предполагаю, что это приоритет операции обновления. Как вы можете видеть здесь DispatcherPriority.Background
имеет только значение 4
. Он будет выполнен после других действий, поставленных в очередь перед ним.
Думаю, поможет, если вы используете DispatcherPriority.Normal
.