【问题标题】:Set up Backgroundworker MVVM, Update a Progressbar设置 Backgroundworker MVVM,更新 Progressbar
【发布时间】:2012-02-06 11:07:02
【问题描述】:

我有一个 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)上的开始按钮时,将执行执行命令。

我现在想要的是更新这些地方的进度条(查看代码),同时加载 ListView。 如何设置 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 中的线程)。但也许你现在对我正在寻找的东西有了更好的了解..

【问题讨论】:

    标签: c# wpf multithreading progress-bar


    【解决方案1】:

    您必须选择:使用一个后台工作人员加载所有列表视图或使用多个后台工作人员,每个工作人员填充一个列表视图。

    目前,您正试图强制后台工作人员在前一项工作完成之前开始处理另一项工作。

    要快速解决此问题:将所有用于加载列表视图的代码放入 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);
    }
    

    要使用多个 Backgroundworkers,请创建多个 Backgroundworkers:

    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.WorkerReportsProgress 属性设置为true 才能启用ReportProgress
    • 问题是,我想隔离代码,这意味着我不想在MainWindow Backgroundcode中编写“ListViewFilling”。我仍然想要它在 Class StartCommand.. ListViewFilling 的样子:viewModel.MissingTables = schemaComparer.GetSchemaModifications<MissingTable>(viewModel.FirstSchemaToCompare, viewModel.SecondSchemaToCompare);
    • 好!您可以做的是将后台工作人员放在 ViewModel 中。
    • 刚刚这样做了,但是我怎样才能访问我的进度条?
    • 在 ViewModel 上创建一个属性 Progress 并将进度条的 Value 属性绑定到它。那就是 MVVM。
    【解决方案2】:

    这一切都取决于“填充列表视图”的实际含义。如果您要去数据库获取数据,那么这绝对应该在后台线程上。但是,如果您已经拥有数据并且只需要填充列表视图,那么 BackgroundWorker 将毫无帮助 - 它会使事情变得更糟。这是因为您需要编组回 UI 线程才能访问 ListView!

    如果您有大量数据要添加到ListView,并且您希望始终保持 UI 响应,则需要在单独的调度程序消息中以块的形式添加数据。添加块后,将另一条消息排队以添加下一个块。这使调度程序有时间在填充列表时处理其他消息。

    【讨论】:

    • 我正在从数据库中获取数据,我同时填充了 7 个 Listview,但它不会花费这么长时间.. 大约 3-7 秒,所以 UI 并不一定是响应式的。 .
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多