有效使用(或替代)System.IO.MemoryStream

时间:2014-05-07 14:57:32

标签: vb.net memorystream imagelist

我有以下代码用于从SQLite数据库填充ImageList,并将图像存储为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,因为我需要以两种不同的尺寸显示图像。

当进程在加载表单时运行时,它会导致进程占用800MB到1GB的系统内存,除非我从表单控件再次手动运行该进程,这似乎会触发垃圾回收。

逐步完成加载过程,很明显是byte2img进程导致内存使用率升级 - 缓解这种情况的最佳方法是什么?

此外,如果任何人都能想到一个更有效的流程来执行此操作,我会全力以赴。图像必须存储在数据库文件中,因为我需要能够立即打包.db文件并立即将其发送到远程位置,因此我无法处理带有图像的文件夹。

所有帮助表示赞赏。

2 个答案:

答案 0 :(得分:4)

您正在创建大量内存流而不会将其丢弃。试试这个:

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中观察HANDLES计数。

答案 1 :(得分:0)

好的,我找到了似乎有用的解决方案/解决方法 - 当用户访问PopulateImageStyles TabPage所在的特定ImageList时调用{{1}}子。

出于某些任意原因,当以这种方式运行时(如上所述,在表单上调用时),进程永远不会消耗超过50-60 MB的工作内存。

我将添加一个后台工作程序,以便可以在不挂起表单的情况下执行该过程。