设置Backgroundworker MVVM,更新进度条
本文关键字:更新 Backgroundworker MVVM 设置 | 更新日期: 2023-09-27 18:22:33
我有一个StartCommand类:
public class StartCommand : ICommand
{
public void Execute(object parameter)
{
//Fill Listview1
...
//Here I want to increase the Progressbarvalue
//Fill Listview2
...
//Here again and so far..
}
}
单击我的MainWindow.xaml
上的"开始"按钮(也是progressBar
)时,将执行"执行命令"。
我现在想要的是在加载ListViews的同时更新这些地方的Progressbar(查看代码)<我该如何设置Backgroundworker>我该如何设置Backgroundworker>
我试过这样的东西:
public class StartCommand : ICommand
{
MainWindow mainWindow;
public StartCommand(MainWindow mainWindow)
{
this.mainWindow = mainWindow
}
public void Execute(object parameter)
{
//Fill Listview1
...
mainWindow.backgroundWorker1.RunWorkerAsync(10);
//Fill Listview2
...
mainWindow.backgroundWorker1.RunWorkerAsync(20);
}
}
主窗口:
public partial class MainWindow : Window
{
BackgroundWorker backgroundWorker1;
public MainWindow()
{
InitializeComponent();
InitializeBackgroundWorker();
}
private void InitializeBackgroundWorker()
{
backgroundWorker1.DoWork +=
new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(
backgroundWorker1_RunWorkerCompleted);
backgroundWorker1.ProgressChanged +=
new ProgressChangedEventHandler(
backgroundWorker1_ProgressChanged);
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
e.Result = UpdateProgressBar((int)e.Argument, worker);
}
private int UpdateProgressBar(int value, BackgroundWorker worker)
{
worker.ReportProgress(value);
return Convert.ToInt32(progressBar.Value);
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
private void backgroundWorker1_ProgressChanged(object sender,ProgressChangedEventArgs e)
{
progressBar.Value = e.ProgressPercentage;
}
}
}
这不起作用(这只是一些复制/粘贴的安排,因为我不知道如何做到这一点,第一次在WPF中使用Threads)。但也许你现在对我要找的东西有了更好的了解。。
您必须选择:使用一个后台工作者加载所有列表视图,或者使用多个后台工作者,每个后台工作者填充一个列表视图。
当前,您正试图迫使后台工作人员在上一个作业完成之前开始另一个作业。
要快速解决此问题,请将加载列表视图的所有代码放在DoWork处理程序中。
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
// fill listview1
worker.ReportProgress(percentageDone);
// fill listview2
worker.ReportProgress(percentageDone);
// fill listview3
worker.ReportProgress(percentageDone);
}
要使用多个后台工作人员,请创建多个后台人员:
var bw1 = new BackgroundWorker();
bw1.DoWork += ...;
bw1.RunAsync(...);
var bw2 = new BackgroundWorker();
bw2.DoWork += ...;
bw2.RunAsync(...);
var bw3 = new BackgroundWorker();
bw3.DoWork += ...;
bw3.RunAsync(...);
这一切都取决于"填充列表视图"的实际含义。如果你要去数据库获取数据,那么它肯定应该在后台线程上。然而,如果您已经有了数据,只需要填充列表视图,那么BackgroundWorker
根本没有帮助——它会让情况变得更糟。这是因为您需要封送回UI线程才能访问ListView
!
如果有大量数据要添加到ListView
,并且希望始终保持UI的响应性,则需要在单独的调度器消息中以块的形式添加数据。添加区块后,将另一条消息排队以添加下一个区块。这使调度程序有时间在填充列表的同时处理其他消息。