自定义进度条指示器在执行耗时操作之前未显示

本文关键字:操作 显示 执行 指示器 自定义 | 更新日期: 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;
}