我制作了一个程序,可以为文件导入一些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
}
}
我现在有两个问题:
因为我的polyline
元素已经属于MainGui线程所以它会抛出System.InvalidOperationException
。我试图用Dispatcher
来解决这个问题。但如果我添加此代码,我的Gui会再次被阻止。将引用的对象polyline
传递给worker的好方法是什么?
this.Dispatcher.Invoke(() =>
{
...// your code here.
});
在每次迭代后,我想更新画布上的polylines
,但不幸的是,这不能正常工作。并且我的ProgressBar
直到迭代结束才更新。有没有办法解决这个问题?
答案 0 :(得分:0)
在我做了一个简短的解决方案以检查我是否能够用MVVM模式解决我的问题后,我认为MVVM对我来说太难以在我的程序中实现,这将花费我太长时间。所以我搜索了我找到的另一种解决方案,并希望向您展示。
<强>解决方案:强>
我与polyline
元素List<List<Point>>
并行实现。我在列表中的点上预先形成所有转移任务,当我想在BackgroundWorker
中更新我的Gui时,我将此任务(请参阅初始帖子中的代码)发送到主线程并覆盖{{1}的点数。 1}}与polyline
。现在我的界面响应,每次迭代后我都可以更新我的Gui。这样我就解决了这两个问题。