自定义进度条指示器在执行耗时操作之前未显示
本文关键字:操作 显示 执行 指示器 自定义 | 更新日期: 2023-09-27 17:59:15
我在WindowsPhone8项目中实现了自定义进度条指示器。如果我试着用一个按钮来切换指示灯,效果会很好。但我当然希望它在我执行耗时的操作(用许多项目填充列表)时显示出来。但是,由于它阻塞了UI,进度条指示器不会在操作之前显示,而是只在操作之后显示。在对列表进行修改之前,我在指示器本身和整个页面上尝试了.UpdateLayout()
,但都不起作用。
customIndeterminateProgressBar.Visibility = System.Windows.Visibility.Visible;
// add ~100 list items
customIndeterminateProgressBar.Visibility = System.Windows.Visibility.Collapsed;
还有别的办法吗?
您可以将耗时的工作卸载到一个新任务中,并添加一个延续以在最后设置进度条可见性。在这里,我使用任务并行库来实现这一点:
customIndeterminateProgressBar.Visibility = System.Windows.Visibility.Visible;
Task.Run(() =>
{
// Do CPU intensive work
}).ContinueWith(task =>
{
customIndeterminateProgressBar.Visibility = System.Windows.Visibility.Collapsed;
}, TaskScheduler.FromCurrentSynchronizationContext());
您应该异步运行繁重的工作(更多关于MSDN和Stephen Cleary博客上的异步),这样它就不会阻塞UI。
一个非常简单的例子是,你有一个ProgressBar和一个沉重的Task
,它会通知PBar它的进度,看起来是这样的:(我已经向Button Click订阅了方法的开始)
private async void StartBtn_Click(object sender, RoutedEventArgs e)
{
var progress = new Progress<double>( (p) =>
{
progresPB.Value = p;
});
await DoSomething(progress); // start asynchronously Task with progress indication
}
private Task<bool> DoSomething(IProgress<double> progress)
{
TaskCompletionSource<bool> taskComplete = new TaskCompletionSource<bool>();
// run your heavy task asynchronous
Task.Run(async () =>
{
for (int i = 0; i < 10; i++) // work divided into parts
{
await Task.Delay(1000); // some heavy work
progress.Report((double)i / 10);
}
taskComplete.TrySetResult(true);
});
return taskComplete.Task;
}