Эффективное использование (или альтернатива) System.IO.MemoryStream
У меня есть следующий код, который я использую, чтобы заполнить ImageList
из базы данных SQLite с изображениями, хранящимися в виде BLOB-объектов.
Public Sub populateImagesStyles()
ShoeImages1.Images.Clear()
StyleImagesLView.Items.Clear()
Dim s As SQLiteDataReader
Dim rcount As Integer = 0
dbLocalQuery = New SQLiteCommand("SELECT id, image FROM tblImages", dbLocal)
s = dbLocalQuery.ExecuteReader()
While s.Read()
rcount += 1
ShoeImages1.Images.Add(CStr(s("id")), byte2img(s("image")))
StyleImagesLView.Items.Add(CStr(s("id")), CStr(s("id")))
End While
s.Close()
Вот функция byte2img...
Public Function byte2img(ByVal imgByte As Byte()) As Image
Dim imgMemoryStream As System.IO.MemoryStream = New System.IO.MemoryStream(imgByte)
byte2img = Drawing.Image.FromStream(imgMemoryStream)
End Function
База данных содержит более 250 изображений, и этот процесс завершается дважды при загрузке, чтобы заполнить два разных ImageList
, потому что мне нужны изображения, отображаемые в двух разных размерах.
Когда процесс запускается при загрузке формы, он заставляет процесс использовать от 800 МБ до 1 ГБ системной памяти, если только я не запустил процесс вручную из элемента управления формы, который, кажется, вызывает сборку мусора.
Проходя процесс загрузки, становится ясно, что именно процесс byte2img вызывает эскалацию использования памяти - как лучше всего это смягчить?
Кроме того, если кто-то может придумать более эффективный процесс для выполнения этого, я весь слух. Изображения должны храниться в файле базы данных, потому что мне нужно иметь возможность просто упаковать файл.db и отправить его в удаленное место в любой момент, чтобы я не мог связываться с папками с изображениями.
Вся помощь приветствуется.
2 ответа
Хорошо, я нашел решение / обходной путь, который, кажется, работает - позвоните PopulateImageStyles
Sub, когда пользователь посещает конкретный TabPage
ImageList
проживает на.
По какой-то произвольной причине при запуске таким способом (как указано выше, при вызове в форме) процесс никогда не переходит к использованию более 50-60 МБ рабочей памяти.
Я добавлю Background Worker, чтобы процесс мог выполняться без зависания формы.
Вы создаете много потоков памяти, не выбрасывая их. Попробуй это:
Public Function byte2img(ByVal imgByte As Byte()) As Image
Dim img As Image
Try
Using ms As New MemoryStream(imgbyte)
img = Drawing.Image.FromStream(ms)
End Using ' auto dispose of the MS
Catch ex As Exception
' report possibly bad/missing imgByte()
' resulting in an error in either place
End Try
Return img
End Function
Неточный способ обнаружить подобные вещи - наблюдать за количеством РУКОВОДСТВ в TaskManager.