Используя C # WPF, я разрабатываю средство просмотра плитки для 2D-игры с игровой сеткой не более 255x255 плиток. Каждая плитка может содержать до 4 оверлейных изображений, которые имеют размер 100x100px .PNG и используют прозрачность. Каждый рисунок имеет размер около 1 КБ.
Моя цель - создать вьюер карт для просмотра карты этих тайлов. Любая данная карта будет иметь размер не более 255x255.
Я хотел сделать это в WPF C #, чтобы воспользоваться преимуществами быстрой разработки, которая идет вместе с ItemsCollections, и полагал, что UniformGrid будет идеальным элементом управления для отображения моей графики и данных плитки.
Настройка программы:
Мой ItemsControl привязан к ItemSource, который является списком класса 'Tile', который я создал. Класс My Tile содержит различные данные о плитке и содержит 4 переменные BitmapImage, которые содержат изображения из нескольких слоев, которые будут отображаться в этой плитке.
Мой шаблон ItemsControl выглядит примерно так, просто чтобы дать представление о структуре:
<ItemsControl ItemSource={Binding MapTiles}>
<ItemSControl.CacheMode>
<BitmapCache/>
</ItemsControl.CacheMode>
<ItemControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="{Binding MapInfo.width}" Columns="{Binding MapInfo.height}">
</ItemsPanelTemplate>
</ItemControl.ItemsPanel>
<Grid>
<Image Source={Binding image1graphic}>
<Image Source={Binding image2graphic}>
<Image Source={Binding image3graphic}>
<Image Source={Binding image4graphic}>
</Grid>
</ItemsControl>
На данный момент я могу успешно загрузить карту тайлов размером 100x100 после долгого ожидания, и мое приложение перестало отвечать на запросы в течение минуты (подробности см. Ниже). После того, как все загружено, программа работает отлично и отзывчиво, однако на больших картах возникают проблемы (см. Ниже)
Вот проблемы с этим подходом, которые, я надеюсь, кто-то может мне помочь ..
Выпуск № 1:
Когда я заполняю свой список MapTiles 100x100, окно приложения будет буквально зависать на одну минуту, пока происходит процесс привязки. Я провел много исследований и не могу понять, как заставить приложение выполнять процесс привязки в фоновом потоке. Похоже, оно выполняет эту операцию массового связывания только в основном потоке графического интерфейса.
Хотя приложение заморожено во время процесса привязки данных, отладчик показывает огромное количество операций по сбору мусора, выполняемых при увеличении использования памяти до 1 ГБ
Когда я пытаюсь увеличить размер до 200x200, у меня возникают проблемы с производительностью и памятью. Процесс привязки данных приводит к тому, что приложение перестает отвечать на запросы в течение до 3 минут, что приводит к взаимоблокировке переключателя контекста в отладчике, и использование памяти иногда достигает 4 ГБ в 32-разрядном режиме и до 8 ГБ в 64-разрядном режиме ( это кажется крайним)
Я позаботился о том, чтобы заморозить все мои BitmapImages после назначения их моему классу плиток, чтобы уменьшить время рендеринга и повысить производительность.
Приложение перестает отвечать на запросы и длительное время привязки данных (1+ минут) является ограничением WPF или, возможно, UniformGrid?
Возможно, есть лучший способ сделать это?
Выпуск № 2:
Хотя мои изображения имеют размер всего 1 КБ, с размером сетки 100x100, что составляет 10 000 плиток, причем каждая плитка содержит до 4 растровых изображений, я предполагаю, что для кэширования потребуется менее 100 МБ памяти. мое приложение использует около 2 ГБ памяти при работе в 32-разрядном режиме и более 6 ГБ памяти при работе в 64-разрядном режиме.
Это нормально? Я знаю, что использование памяти WPF отличается от традиционных приложений Windows Forms, однако я не уверен, почему используется такой большой объем памяти.
Возможно, это как-то связано с тем, как кэширование и привязки данных работают в моей настройке? Любая помощь будет оценена