Эффективное использование (или альтернатива) 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.

Другие вопросы по тегам