Why is my WPF splash screen progress bar out of sync with the execution of the startup steps?
I've implemented a simple WPF splash screen window which informs the user about the progress of the application startup.
The startup steps are defined this way:
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
etc. are methods defined elsewhere, which performs some time consuming tasks.
The boot sequence gets executed this way:
foreach (var step in bootSequence)
{
_status.Update(step.Message);
step.Do();
}
_status
denotes an instance of my XAML splash screen window containing a progress bar and a label for status information. Its Update()
method is defined as follows:
public void Update(string status)
{
int value = ++_updateSteps;
Update(status, value);
}
private void Update(string status, int value)
{
var dispatcherOperation = Dispatcher.BeginInvoke(
DispatcherPriority.Backgro开发者_开发问答und,
(ThreadStart) delegate
{
lblStatus.Content = status;
progressBar.Value = value;
});
dispatcherOperation.Wait();
}
In the main this works, the steps get executed and the splash screen shows the progress. But I observed that the splash screen for some reasons doesn't update its content for all steps. This is the reason I called the Dispatcher async and wait for its completion. But even this didn't help.
Has anyone else experienced this or some similar behaviour and has some advice how to keep the splash screen's update in sync with the execution of the boot sequence steps? I know that the users will unlikely notice this behaviour, since the splash screen is doing something and the application starts after booting is completed. But myself isn't sleeping well, because I don't know why it is not working as expected...
Thx for your help, Denny
my guess is the priority of the update operation. As you can see here DispatcherPriority.Background
has only the value 4
. It will be executed after other action queued before it.
I think, it should help if you use DispatcherPriority.Normal
.
Finally, I've found a simple solution to my problem: I execute time consuming startup steps in a background worker! That gave the ui thread its responsiveness back...
精彩评论