Ускорить добавление объектов к canvasу В WPF

У меня есть Canvas который я использую в WPF, чтобы рисовать много цветных прямоугольников, но программа работает очень медленно, когда они добавляются. Я пробовал различные варианты, например, добавляя их в Array и добавляя их все сразу и используя вместо изображения Canvas для их отправки, но они, похоже, мало что делали. У меня есть кодирование, ведущее вверх по чертежу в streamе, но из-за правил C # я должен иметь часть чертежа в основном streamе. Я должен также отметить, что проблема не в моем компьютере (его работает Intel Core i7 с 14 ГБ оперативной памяти DDR2).

Это код, который добавляет прямоугольники. Прошло более 83 000 раз.

  private void AddBlock(double left, double top, double width, double height, Brush color) { if (this.Dispatcher.Thread != Thread.CurrentThread) { this.Dispatcher.Invoke(new Action(this.AddBlock), left, top, width, height, color); return; } Rectangle rect = new Rectangle() { Width = width, Height = height, Fill = color, SnapsToDevicePixels = true }; this.canvas.Children.Add(rect); Canvas.SetLeft(rect, left); Canvas.SetTop(rect, top); } 

ПРИМЕЧАНИЕ. Как я уже сказал в комментарии ниже, я хотел бы что-то, что позволяет ему запускаться в отдельном streamе (даже если это связано с работой с P / Invoke), поскольку, похоже, не существует жизнеспособного решения только для использования C # и WPF ,

Какие-либо предложения?

Использование метода OnRender

Я создал class, наследующий Canvas, и переопределить метод OnRender, чтобы получить DrawingContext и использовать его для рисования. поэтому в коде я не добавляю прямоугольники в canvas, а в правый список в новом classе и вызываю InvalidateVisual(); используя диспетчер, как только я закончил с добавлением.

 class MyCanvas:Canvas { public class MyRect { public Rect Rect; public Brush Brush; } public List rects = new List(); protected override void OnRender(System.Windows.Media.DrawingContext dc) { base.OnRender(dc); for (int i = 0; i < rects.Count; i++) { MyRect mRect = rects[i]; dc.DrawRectangle(mRect.Brush, null, mRect.Rect); } } } 

XAML

  

добавить исправления

 private void AddBlock(double left, double top, double width, double height, Brush color) { canvas.rects.Add(new MyCanvas.MyRect() { Brush = color, Rect = new Rect(left, top, width, height) }); } 

обновлять, когда готово, должно быть сделано на диспетчере

 canvas.InvalidateVisual(); 

Это, по-видимому, самый быстрый способ рисовать в WPF, вам может не понадобиться до GDI + или pinvoke. Во время тестов в моей системе исходный код занимал около 500 ms для рендеринга 830 rects а geometry занимала примерно 400 мс для визуализации того же самого, где, поскольку этот подход отображал 83,000 rects менее чем за 100 ms

Также я бы посоветовал вам добавить некоторое кэширование, чтобы избежать чрезмерного

Решение с использованием геометрии

переменные уровня classа

 GeometryGroup gGroup; 

подготовьте, используя следующий код

 DrawingBrush dBrush= new DrawingBrush(); gGroup = new GeometryGroup(); GeometryDrawing gDrawing = new GeometryDrawing(Brushes.Red, null, gGroup); dBrush.Drawing = gDrawing; Canvas.Background = dBrush 

затем приходит ваш код

 private void AddBlock(double left, double top, double width, double height, Brush color) { if (this.Dispatcher.Thread != Thread.CurrentThread) { this.Dispatcher.Invoke(new Action(this.AddBlock), left, top, width, height, color); return; } //color need to figure out as it is added in GeometryDrawing //currently Brushes.Red defined earlier gGroup.Children.Add(new RectangleGeometry(new Rect(left, top, width, height))); } 

Этот образец может помочь вам достичь того же. Я также сделаю некоторый эксперимент в ближайшее время, чтобы получить желаемый результат намного быстрее.

  • Улучшить производительность SQLite в секунду в секунду?
  • Что лучше ? Несколько операторов if, или один, если с несколькими условиями
  • Когда, если когда-либо, цикл разворачивания по-прежнему полезен?
  • Minify Html выход приложения ASP.NET
  • Помощь оптимизации цикла цикла для окончательного назначения
  • Что такое примечание Big O? Вы используете его?
  • Встроенные функции в C #?
  • Поиск ближайшего соседа с использованием оптимизированного алгоритма Левенштейна
  • Должны ли операции импорта всегда находиться в верхней части модуля?
  • Почему моя функция NLTK замедляется при обработке DataFrame?
  • Почему условный ход не уязвим для отказа от ветвления?
  • Давайте будем гением компьютера.