WPF - рисовать несколько прямоугольников на холсте параллельно - PullRequest
0 голосов
/ 14 января 2020

У меня есть класс BBox, который представляет Rectangle - он содержит координаты (x, y, width, height) и цвет прямоугольника. Тогда у меня есть список этих BBox, который содержит около 4000 из них. Мне нужно как можно быстрее нарисовать все поля, которые хранятся в списке на холсте. Какой самый эффективный способ?

    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);
            }

}

Код выше занимает больше 1 секунды, что медленно для моего приложения. Я уверен, что должен быть способ сделать это параллельно. Поэтому я попробовал это:

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

, но выбрасывает

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

Я знаю, почему происходит это исключение, и я пытался найти решение, но у меня ничего не работает. Например, я попытался запустить его, используя Dispatcher.Invoke (() => или запустить его, используя новый Thread , как указано здесь:

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

, но он все еще выбрасывает упомянутое исключение. Как я могу решить эту проблему? Или есть ли лучший / более эффективный способ рисовать несколько объектов на холсте? Спасибо.

1 Ответ

0 голосов
/ 18 января 2020

Хорошо, я решил свою проблему, используя WriteableBitmapEx , как рекомендовал Клеменс. Теперь 4000+ ящиков отрисовываются в режиме реального времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...