C #, WinForms Рисование данных, хранящихся в ArrayList. Это хорошая идея? - PullRequest
0 голосов
/ 23 ноября 2011

В моем случае у меня есть 2D ArrayList, полный объектов, в которых есть данные, которые используются при рисовании горизонтальных линий, вертикальных линий и заполненных прямоугольников.В разных случаях количество объектов разное, а на изображении разное количество нарисованных линий и прямоугольников.Но изображение нужно иногда перерисовывать.Чем больше нужно перерисовать, тем сильнее мигает экран (надеюсь, вы можете понять, что я имею в виду под «вспышками»).

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

Я прочитал, что легко добавлять и удалять элементы (независимо от типа) в любом месте изArrayList, но доступ к ним затруднен.Я также читал, что List работает лучше, чем ArrayList (означает ли это, что программе потребуется меньше ресурсов для компьютера?), Но добавлять и удалять элементы с конца легко.Но я не уверен, что производительность Array самая быстрая.И это заставляет меня думать, что вспышки могут стать слабее, если я изменю ArrayList с помощью Array или List.

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

Мой вопрос: могу ли я ослабить вспышки, если я заменю ArrayList на Array или List?

Ответы [ 4 ]

1 голос
/ 23 ноября 2011

ОК, здесь две проблемы.Вопрос ArrayList и List не влияет на «перепрошивку», поскольку разница в производительности невелика.Если все элементы списка имеют один и тот же тип или все они происходят от общего базового типа, отличного от object, или если все они реализуют общий интерфейс, то List<T> - лучший выбор.Это потому, что меньше кастингов или даже боксов / распаковок.Кроме того, вам будет проще получить доступ к вашим элементам.

Мигает: все рисование выполняется методом рисования (вашей формы или какого-либо элемента управления).Затем вызовите метод Invalidate этой формы или элемента управления.Не рисуй "напрямую".В качестве улучшения вы можете передать прямоугольную структуру в Invalidate, сообщая, какая часть должна быть перерисована.В методе рисования вы можете проверить e.ClipRectangle, который говорит вам, какую часть нужно перерисовать.Это дает вам возможность внести некоторые улучшения здесь.Однако следует помнить о том, что сама ОС Windows может инициировать недействительный вывод, что приводит к произвольным ClipRectangles.

1 голос
/ 23 ноября 2011

Сравнивая производительность рисования с чтением из производительности ArrayList, вы не можете решить проблему мерцания, используя другой контейнер данных.Таким образом, альтернативный контейнер ArrayList не является ответом.Вам нужно использовать некоторые другие методы, такие как:

  • Использование SDL, DirectX, OpenGL как графической библиотеки.
  • Рисование в буфер растровых изображений и отображение растрового изображения послеоно завершено (похоже на двойную буферизацию, но иногда оно работает лучше).
  • Подклассирование некоторых компонентов и переопределение некоторых методов, таких как рисование фона.

Есть еще больше методов, но ответВаш вопрос определенно не имеет ничего общего с ArrayList.

1 голос
/ 23 ноября 2011

Вы должны использовать List<T> вместо ArrayList, просто чтобы избавиться от ненужного приведения при чтении объектов из списка. Однако прирост производительности от этого настолько мал по сравнению с рисованием графики, что он не окажет заметного влияния на проблему обновления.

Вы можете рассмотреть возможность отрисовки графики в растровое изображение, а затем нарисовать растровое изображение, когда вам нужно обновить экран.


A List<T> и ArrayList ведут себя одинаково, когда дело доходит до добавления и удаления элементов; дешево добавлять или удалять элементы в конце списка, но дороже вставлять или удалять элементы в начале списка.

Массив является самым быстрым из списков, и оба List<T> и ArrayList используют массивы для внутреннего хранения своих элементов. Тем не менее, вы не можете изменить размер массива, поэтому вы все равно можете использовать List<T>, так как он выполняет работу по размещению массивов по мере необходимости и отслеживает, сколько массива используется.

0 голосов
/ 23 ноября 2011

Чтобы исправить «вспышки», необходимо включить двойную буферизацию.

Вы не должны использовать ArrayList, потому что он поощряет ошибки и / или плохой дизайн.
У вас не должно быть списков, содержащих несколько типов объектов.

Вместо этого вы должны использовать List<T>, возможно, с полиморфным базовым классом.

...