In my WPF application I have a for
loop that after a button click manipulates a Canvas
control.
for (var i = 0; i < numOfIterations; i++)
{
swarm.iterate();
myCanvas.Children.Clear();
for (int j = 0; j < numCities - 1; j++)
{
Line line = new Line();
line.Stroke = System.Windows.Media.Brushes.Black;
line.X1 = ScaleX(cities[swarm._gbestlist[j]].x, maxX);
line.X2 = ScaleX(cities[swarm._gbestlist[j + 1]].x, maxX);
line.Y1 = ScaleY(cities[swarm._gbestlist[j]].y, maxY);
line.Y2 = ScaleY(cities[swarm._gbestlist[j + 1]].y, maxY);
line.StrokeThickness = 2;
myCanvas.Children.Add(line);
}
}
As you probably know, the UI is not responsive during the execution of the loop and after the loop finished, the result after last iteration is visible. What should I do to have a "live" preview of the lines being added and deleted?
I tried using BackgroundWorker
:
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
double maxX = FindMaxX();
double maxY = FindMaxY();
for (int i = 0; i < 250; i++)
{
swarm.iterate();
RemoveLines();
for (int j = 0; j < cities.Count - 1; j++)
{
Line line = new Line();
line.Stroke = System.Windows.Media.Brushes.Black;
line.X1 = ScaleX(cities[swarm._gbestlist[j]].x, maxX);
line.X2 = ScaleX(cities[swarm._gbestlist[j + 1]].x, maxX);
line.Y1 = ScaleY(cities[swarm._gbestlist[j]].y, maxY);
line.Y2 = ScaleY(cities[swarm._gbestlist[j + 1]].y, maxY);
line.StrokeThickness = 2;
myCanvas.Children.Add(line);
}
}
}
But I get
System.InvalidOperationException was unhandled by user code: The calling thread cannot access this object because a different thread owns it.
Invoke
) or split cycle into steps and use timer to progress through them. – SinatrBackgroundWorker
. Please, see the edit. It seems like I can not modify UI elements from a different thread. – pmichna