views:

326

answers:

2

Hello,

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.Background,
        (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

A: 

Hi,

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.

DHN
I've tried several dispatcher priorities - normal amongst them - but the behavior is the same. Anyway, since the update method waits on the dispatcher to return, the priority shouldn't matter.
denny_ch
Ok. Hmm, curios...why do you wait on the dispatcher to return? I think it's not necessary, because other following calls will be queued later because they all have the same priority.
DHN
I wait on the dispatcher because I thought that would ensure that the progress bar and status info in the splash screen always corresponds to the boot seq step which is currently under execution.
denny_ch
Ok, I understand your intention. But do you really think this is necessary? A splash screen is just for showing 'Yeah, I'm alive. I'm doing someting.'. I don't think it has to be that synchronous.Additionally, you are slowing down your startup with it, because you invoke and then wait for the end. But at this moment several other actions could be queued and will be executed before. It's not really a good idea, is it?
DHN
You're completely right - it's not necessary to keep the splash screen in sync. I'm just curious about the reason why the screen isn't working as expected from a developer point of view. Let's close this case and find other things which are more worth to waste ..ähem... spend our time. Thx for your comments!
denny_ch
A: 

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...

denny_ch