1

我已经实现了一个简单的 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();
}

这主要是有效的,步骤被执行,启动屏幕显示进度。但我观察到,由于某些原因,闪屏并没有更新所有步骤的内容。这就是我调用 Dispatcher async 并等待其完成的原因。但即使这样也无济于事。

是否有其他人经历过这种或类似的行为,并且有一些建议如何使启动屏幕的更新与启动顺序步骤的执行保持同步?我知道用户不太可能注意到这种行为,因为启动屏幕正在执行某些操作,并且应用程序在启动完成后启动。但是我自己睡得不好,因为我不知道为什么它没有按预期工作......

谢谢你的帮助,丹尼

4

2 回答 2

1

我的猜测是更新操作的优先级。如您所见,这里 DispatcherPriority.Background只有 value 4。它将在它之前排队的其他操作之后执行。
我认为,如果您使用DispatcherPriority.Normal.

于 2010-05-17T10:52:35.470 回答
1

最后,我找到了解决问题的简单方法:我在后台工作程序中执行耗时的启动步骤!这让 ui 线程恢复了响应能力......

于 2010-05-22T19:09:35.807 回答