在BackgroundWorker中编辑wpf Gui对象

时间:2016-11-29 11:13:47

标签: c# wpf canvas backgroundworker

我制作了一个程序,可以为文件导入一些polyline数据。之后,我必须使用wpf polyline元素执行一些移位任务。最初我只做了一次迭代,在计算过程中阻止Gui是没问题的。但是,如果我进行多次移动迭代,Gui会被阻塞一段时间。因此,我添加了BackgroundWorker来解决问题。我的程序结构可以在这里看到:

class MainGui
{
    private readonly BackgroundWorker worker = new BackgroundWorker();
    List<Polyline> _lines;
    int _iterationCount = 10;

    public MainGui()
    {
        worker.DoWork += worker_DoWork;
        worker.WorkerReportsProgress = true;
        worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
    }

    public void MainTask()
    {
        _lines = Import.ImportLines();

        DrawLines(_lines);
    }

    private void button_Click(object sender, RoutedEventArgs e)
    {
        worker.RunWorkerAsync();
    }

    private void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        for (int i = 0; i < _iterationCount; i++)
        {
            ShiftTask.DoShift(_lines);

            // worker.ReportProgress((int)((_workerProgressBase - _overlFid[0].Count) / _workerProgressBase * 100));
            (sender as BackgroundWorker).ReportProgress((int)((_iterationCount - i) / _iterationCount * 100));

            // here I would like to update my canvas
        }
    }

    private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        ProgressBar.Value = e.ProgressPercentage;
    }

    private void DrawLines(List<Polyline> lines)
    {
        // draw lines on wpf canvas
    }
}

我现在有两个问题:

  1. 因为我的polyline元素已经属于MainGui线程所以它会抛出System.InvalidOperationException。我试图用Dispatcher来解决这个问题。但如果我添加此代码,我的Gui会再次被阻止。将引用的对象polyline传递给worker的好方法是什么?

    this.Dispatcher.Invoke(() =>
    {
      ...// your code here.
    });
    
  2. 在每次迭代后,我想更新画布上的polylines,但不幸的是,这不能正常工作。并且我的ProgressBar直到迭代结束才更新。有没有办法解决这个问题?

1 个答案:

答案 0 :(得分:0)

在我做了一个简短的解决方案以检查我是否能够用MVVM模式解决我的问题后,我认为MVVM对我来说太难以在我的程序中实现,这将花费我太长时间。所以我搜索了我找到的另一种解决方案,并希望向您展示。

<强>解决方案:

我与polyline元素List<List<Point>>并行实现。我在列表中的点上预先形成所有转移任务,当我想在BackgroundWorker中更新我的Gui时,我将此任务(请参阅初始帖子中的代码)发送到主线程并覆盖{{1}的点数。 1}}与polyline。现在我的界面响应,每次迭代后我都可以更新我的Gui。这样我就解决了这两个问题。