Search code examples
c#wpfparallel-processingdrawing

WPF - Draw multiple Rectangles on Canvas in parallel


I have class BBox, which repesents Rectangle - it contains cooridinates(x, y, width, height) and color of rectangle. Then I have List of these BBoxes, which contains circa 4000 of them. I need to draw all boxes which are stored in a List on a Canvas as fast as possible. What is the most effective way?

    private List<BBox> FoundBoxes { get; set; }

    public void DrawBoxes(Canvas canvas)
    {
            foreach (var box in FoundBoxes)
            {
                var brush = box.getColor();
                System.Windows.Shapes.Rectangle rect;
                rect = new System.Windows.Shapes.Rectangle
                {
                    Stroke = brush,
                    Height = box.Height,
                    Width = box.Width,
                    StrokeThickness = 1
                };
                Canvas.SetLeft(rect, box.TopLeftX);
                Canvas.SetTop(rect, box.TopLeftY);
                canvas.Children.Add(rect);
            }

}

Code above takes more than 1 second, which is slow for my application. I am sure that there must be a way to do it in parallel. So I tried this:

 Parallel.ForEach(FoundBoxes, box =>
 {
      ...same method body...
 });

but it throws

System.InvalidOperationException: 'The calling thread must be STA, because many UI components require this.'

I am aware why this exceprtion occurs, and I tried to find solution, but nothing works for me. For example I tried running it using Dispatcher.Invoke(() => or running it using new Thread as stated here:

Thread t = new Thread(delegate ()
{
    Parallel.ForEach(FoundBoxes, box =>
    {
      ...same method body...
    });
});
t.SetApartmentState(ApartmentState.STA);
t.IsBackground = true;
t.Start();

but it still throws mentioned exception. How can I solve this? Or is there any better / more effective way to draw multiple objects on canvas? Thank you.


Solution

  • Allright I solved my problem using WriteableBitmapEx as Clemens recommended. Now, 4000+ boxes are drawn in real-time.