我正在使用Vb.NET Windows窗體應用程序,並且存在從內存中加載圖像的網格,它佔用了太多內存的一小部分時間,如果低內存,有時程序崩潰。 提出了一種解決方案,通過使用直接內存流並從URL加載圖片來消耗更少的內存。如何從線程中的直接URL加載GridView圖像
但我正在使用數據網格視圖,我需要把我所有的處理放在一個線程中,因此,它安全地加載圖片,程序不會卡住。
以下是從URL獲取圖像並將其附加到GridView Cell的代碼,任何人都可以引導我如何投入線程。
Private Function GetBitmapFromLink(ByVal ImagePath As String) As Image
Dim exp As Boolean = False
Try
Dim request As System.Net.WebRequest = System.Net.WebRequest.Create(ImagePath)
Dim response As System.Net.WebResponse = request.GetResponse()
Dim responseStream As System.IO.Stream = response.GetResponseStream()
Dim Img As New Bitmap(responseStream)
If Img IsNot Nothing Then
Return Img
End If
Catch ex As Exception
WriteToLog(ex)
End Try
End Function
'Using here in loop
CType(dr.Cells("img1"), DataGridViewImageCell).Value = GetBitmapFromLink(ImagePath & dtImages.Rows(i)("ImageName"))
這裏是comlete代碼:
Sub SetSource(ByVal dtImages As DataTable)
Try
Dim ImagePath As String = BaseUrl
ImagePath = ImagePath.Replace("/a", "/p") & "vs/"
LockWindowUpdate(Me.Handle)
Try
For Each dRow As DataRow In grdSent.Rows
CType(dRow("img1"), DataGridViewImageCell).Value = Nothing
CType(dRow("img2"), DataGridViewImageCell).Value = Nothing
Next
Catch ex As Exception
End Try
grdSent.Rows.Clear()
Dim i As Integer = 0
While (True)
Dim drIndx As Integer
Dim dr As DataGridViewRow
If (dtImages.Rows.Count > i AndAlso dtImages.Rows(i)("image") IsNot DBNull.Value) Then
drIndx = grdSent.Rows.Add()
dr = grdSent.Rows(drIndx)
Dim ms As New MemoryStream(CType(dtImages.Rows(i)("image"), Byte()))
'CType(dr.Cells("img1"), DataGridViewImageCell).Value = Image.FromStream(ms)
CType(dr.Cells("img1"), DataGridViewImageCell).Value = GetBitmapFromLink(ImagePath & dtImages.Rows(i)("ImageName"))
dr.Cells("img1").Tag = dtImages.Rows(i)("id")
ms.Close()
Else
Exit While
End If
i = i + 1
If (dtImages.Rows.Count >= i) Then
Try
Dim ms As New MemoryStream(CType(dtImages.Rows(i)("image"), Byte()))
'CType(dr.Cells("img2"), DataGridViewImageCell).Value = Image.FromStream(ms)
CType(dr.Cells("img2"), DataGridViewImageCell).Value = GetBitmapFromLink(ImagePath & dtImages.Rows(i)("ImageName"))
dr.Cells("img2").Tag = dtImages.Rows(i)("id")
ms.Close()
Catch ex As Exception
CType(dr.Cells("img2"), DataGridViewImageCell).Value = My.Resources.WhiteDot
dr.Cells("img2").Tag = -1
End Try
Else
Exit While
End If
i = i + 1
End While
If (grdSent.RowCount > 0) Then
'If (grdSentiments.Rows(grdSent.RowCount - 1).Cells("img1").Value Is My.Resources.WhiteDot AndAlso grdSentiments.Rows(grdSent.RowCount - 1).Cells("img2").Value Is My.Resources.WhiteDot) Then
' grdSentiments.Rows.RemoveAt(grdSent.RowCount - 1)
'End If
End If
Catch ex As Exception
WriteToLog(ex)
Finally
LockWindowUpdate(0)
End Try
End Sub
根據您的編輯,你的情況爲.NET 3.5這足以在另一個線程中調用'SetSource'。你可以在'Backgroundworker'的'DoWork'事件中做或者使用'Thread'來做到這一點。 Anywan,在你的方法中,你應該應用一些改變。在你訪問一個UI元素的每個地方,你應該使用'Invoke'來防止一個跨線程操作異常。 –