为什么我的 WPF 初始屏幕进度条与启动步骤的执行不同步?
我实现了一个简单的 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 并等待其完成的原因。但即使这样也无济于事。
有没有其他人经历过这种或类似的行为,并有一些建议如何使启动屏幕的更新与启动序列步骤的执行同步?我知道用户不太可能注意到这种行为,因为启动画面正在执行某些操作并且应用程序在启动完成后启动。但我自己睡得不好,因为我不知道为什么它没有按预期工作......
谢谢你的帮助, 丹尼
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我的猜测是更新操作的优先级。正如您在此处
看到的DispatcherPriority.Background
仅具有值4
。它将在之前排队的其他操作之后执行。我认为,如果您使用 DispatcherPriority.Normal 应该会有所帮助。
my guess is the priority of the update operation. As you can see here
DispatcherPriority.Background
has only the value4
. It will be executed after other action queued before it.I think, it should help if you use
DispatcherPriority.Normal
.最后,我找到了解决问题的简单方法:我在后台工作人员中执行耗时的启动步骤!这让 ui 线程恢复了响应能力......
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...