我有一个很长的操作,可以在主UI上创建一些工具。
当我运行此操作时,UI会挂起。
我想更新ProgressBar
以指示操作状态百分比,但它不会更新。
我的代码如下所示:
Sub DoWork()
DoLongOperation()
End sub
sub DoLongOperation()
For K as integer = 0 to 50
'Here I create tools and add them to a StackPanel in the window
'While doing this I update a progressBar value
ProgressBar1.value=Some value
Next
End sub
我该怎么做? 我尝试了异步等待,但它无法处理为主UI创建工具的操作。
答案 0 :(得分:0)
ProgressBar未更新的原因是您仍然阻止主线程。应该在另一个线程中调用您的长操作。所以你可以使用例如Task.Run方法。 还有一件事要记住,在另一个线程中你不能改变任何UI,你应该使用你的窗口的Dispatcher属性。
private void Button_Click(object sender, RoutedEventArgs e)
{
Task.Run(() =>
{
for(int i = 0; i < 50; i++)
{
Thread.Sleep(1000); // some long operation
var progress = i*2;
Dispatcher.Invoke(() =>
{
progressBar1.Value = progress;
});
}
});
}
答案 1 :(得分:0)
如前所述,为了更新UI,或者在执行非常长的操作时仍然使其解锁和可用,您必须在其他线程中执行该操作。您可以使用BackgroundWorker
来执行此操作。如果您不想为新线程创建新方法,您可以委派它们,这样您就可以这样做:
Imports System.ComponentModel
Sub DoLongOperation()
Dim bgWorker As New System.ComponentModel.BackgroundWorker()
bgWorker.WorkerReportsProgress = True
AddHandler bgWorker.DoWork,
Sub(sender, args)
For K as integer = 0 to 50
'Here I create tools and add them to a StackPanel in the window
'While doing this I update a progressBar value
bgWorker.ReportProgress(123)
Next
End Sub
AddHandler bgWorker.ProgressChanged,
Sub(sender, args)
ProgressBar.Value = args.ProgressPercentage
End Sub
AddHandler bgWorker.RunWorkerCompleted,
Sub(sender, args)
End Sub
End sub
由于您无法在StackPanel
上的其他帖子中添加/删除或执行其他操作,因此您可以将要添加的项目放入bgWorker.ReportProgress()
方法,然后从{{1事件所以就是这样:
.ProgressChanged
答案 2 :(得分:0)
我明白了。我把我的创作分为50个部分。在创建一个工具结束时,我可以设置进度条。之后,我可以创建第二个。然后继续。