Click here to Skip to main content
15,851,242 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more: , +
Using the following code I get the OutOfMemory error, I noticed that new threads are started continuously, how do I control the number of threads or reuse previously created? where am I wrong? Hothanks

VB
Module Module1

Dim TotalThread As Integer = 3
Dim SemaphoreCount As Integer = 2
Dim Threads As Thread() = New Thread(TotalThread - 1) {}
Dim semaph As New Semaphore(SemaphoreCount, SemaphoreCount)

Private baseUrl As String = "http://www.domain.com"
Private m_SavePath As String = "c:\test\"

Public Structure ParameterList
    Public ImageUrl As String
    Public FileName As String
    Public objSemaphore As Semaphore
End Structure

<MTAThread> _
Sub Main()
   checkImage() 
End Sub

Private Function checkImage() As Boolean

    Dim _param As New ParameterList

    Dim dbConn As New SqlClient.SqlConnection("Data Source=localhost\sqlexpress;Initial Catalog=db;Persist Security Info=True;User ID=username;Password=password")
    dbConn.Open()
    Dim cmd As New SqlCommand
    cmd.Connection = dbConn
    cmd.CommandType = CommandType.Text
    cmd.CommandText = "SELECT  LinkImg.codice , LinkImg.foto , LinkImg.Zoom FROM LinkImg WHERE codice NOT IN (select codice from _PRODOTTI_IMMAGINI)"

    Dim dtr As SqlDataReader

    Try
        dtr = cmd.ExecuteReader(CommandBehavior.CloseConnection)

        If dtr.HasRows Then
            While dtr.Read

                Dim t1 As New Thread(New ParameterizedThreadStart(AddressOf DownloadRemoteImageFile))
                Dim t2 As New Thread(New ParameterizedThreadStart(AddressOf DownloadRemoteImageFile))

                _param.ImageUrl = dtr("zoom")
                _param.FileName = "img_zoom_" & dtr("codice").ToString.Trim & ".jpg"
                _param.objSemaphore = semaph

                t1.IsBackground = True
                t1.Start(_param)

                _param.ImageUrl = dtr("foto")
                _param.FileName = "img_Small_" & dtr("codice").ToString.Trim & ".jpg"
                _param.objSemaphore = semaph

                t2.IsBackground = True
                t2.Start(_param)

                t1 = Nothing
                t2 = Nothing

            End While
        End If

    Catch ex As Exception
        Throw ex
    Finally
        dbConn.Close()
    End Try

    Return True
End Function

Public Sub DownloadRemoteImageFile(ByVal param As Object)

    Dim l_SemaPhore As Semaphore = DirectCast(param.objSemaphore, Semaphore)

    If l_SemaPhore.WaitOne(100, False) Then
        Try
            Dim imageUrl As String = baseUrl & param.ImageUrl

            Dim imageBytes As Byte()
            Dim imageRequest As HttpWebRequest = DirectCast(WebRequest.Create(imageUrl), HttpWebRequest)
            Dim imageResponse As HttpWebResponse = TryCast(imageRequest.GetResponse(), HttpWebResponse)

            If (imageResponse.StatusCode = HttpStatusCode.OK OrElse imageResponse.StatusCode = HttpStatusCode.Moved OrElse imageResponse.StatusCode = HttpStatusCode.Redirect) AndAlso imageResponse.ContentType.StartsWith("image", StringComparison.OrdinalIgnoreCase) Then
                Dim responseStream As Stream = imageResponse.GetResponseStream()

                Using br As New BinaryReader(responseStream)
                    imageBytes = br.ReadBytes(500000)
                    br.Close()
                End Using

                responseStream.Close()
                imageResponse.Close()

                Dim fs As FileStream
                Dim bw As BinaryWriter

                Try
                    fs = New FileStream(m_SavePath & param.FileName.Replace("/", "-"), FileMode.Create)
                    bw = New BinaryWriter(fs)

                    bw.Write(imageBytes)
                Catch ex As Exception

                Finally
                    If fs IsNot Nothing Then fs.Close()
                    If bw IsNot Nothing Then bw.Close()
                End Try

                Thread.Sleep(200)

            End If

        Finally
            l_SemaPhore.Release()
        End Try
    End If
End Sub
End Module
Posted

1 solution

Why are you starting a pair of new threads on eavry record read? Every thread comes with a cost. They are expensive to spin up and cost you 1MB of memory for its stack.

Google for "Task class" and convert this code to spin up a Task instead. Tasks will only use enough threads to keep the processor busy and manage its own queue of work to be done without you doing anything special.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900