0

This question appears multiple times on StackExchange but I just can't solve it. Most answers say that this arises due to SSL or TLS issues and to set the protocol to TLS10 or to use KeepAlive.

In my case, I am calling my own PHP endpoint and not using SSL. The server is hosted on GoDaddy.

I am retrieving records from the server. Due to the large size of the returned data, I placed the calls in a loop. The loop runs and fetches data for 40-50 iterations before throwing this error. It is not a timeout issue as the error is thrown within milliseconds.

I suspect a stream or connection is not closing and the VB.Net program is running out of resources or the server has too many open connections.

The code below is slightly abridged to remove sensitive info:

        While True

        ' Create the request
        uri = New Uri(My.Settings.ServerURL & My.Settings.GetEmployeeRecords)
        request = DirectCast(WebRequest.Create(uri), HttpWebRequest)
        ' Add user credentials
        creds = New CredentialCache
        creds.Add(uri, "Basic", New NetworkCredential(My.Settings.UserId, My.Settings.Password))
        With request
            .Method = "POST"
            .ContentType = "application/x-www-form-urlencoded"
            .AutomaticDecompression = DecompressionMethods.GZip + DecompressionMethods.Deflate
            .Credentials = creds
            .KeepAlive = False
            .ProtocolVersion = HttpVersion.Version10
            .ConnectionGroupName = Guid.NewGuid().ToString()
            .UserAgent = "VB.NET App"
            .AllowAutoRedirect = False
        End With
        ' Add parameters
        strPostData = String.Format("offset={0}&limit={1}", iOffset, iLimit)
        request.ContentLength = strPostData.Length

        Try
            Using sw As New StreamWriter(request.GetRequestStream)
                sw.Write(strPostData)
                sw.Close()
            End Using
        Catch ex As Exception
            e.Result = "Error Setting Request Data"
            Exit Sub
        End Try

        ' Send the request to the server
        Try
            response = DirectCast(request.GetResponse, HttpWebResponse)
        Catch ex As WebException
            e.Result = "Error Sending Request" **<-- This is where it is thrown**
            Exit Sub
        End Try

        ' Open the response
        Try
            reader = New StreamReader(response.GetResponseStream)
        Catch ex As Exception
            e.Result = "Error Reading Request"
            Exit Sub
        End Try

        ' Read the full response
        rawresp = reader.ReadToEnd()
        reader.Close()
        response.Close()

        ' We should never get a blank response
        If rawresp = "" Or rawresp = "[]" Then
            e.Result = "Blank Response"
            Exit Sub
        End If

        ' The response should be in JSON. Parse it
        Try
            jResults = Linq.JObject.Parse(rawresp)
        Catch ex As Exception
            e.Result = "Error parsing response"
            Exit Sub
        End Try

        ' Get the complete response into jResults
        ' The jResults would contain {statuscode, statusDescription, data[]} where the data element would be an array of employees
        ' Check for error returned in response JSON
        If jResults("statusCode").ToString = "404" Then
            Exit While
        End If
        If jResults("statusCode").ToString <> "0" Then
            e.Result = "Error received from server"
            Exit Sub
        End If

        ' Get the array for the employee records
        Try
            jEmployees = Linq.JArray.Parse(jResults("data").ToString)
        Catch ex As Exception
            e.Result = "Response Does Not Contain Employee Array"
            Exit Sub
        End Try
        ' Everything is fine. Add the recordds to the local database
        SaveEmployeesToLocalDB(jEmployees)
        iCount = jEmployees.Count
        iOffset += iCount
        iTotalRecords += iCount
        If iCount = 0 Then
            Exit While
        End If
        If iTotalRecords Mod (20 * iLimit) = 0 Then
            Application.DoEvents()
            Threading.Thread.Sleep(3000)
        End If
    End While
Hussain Akbar
  • 646
  • 8
  • 25
  • 1
    Unrelated to your issue, but using `Application.DoEvents()` to try to keep your UI responsive is really bad practice and you should remove it now. You need to run your code in a thread. See this for more info: https://stackoverflow.com/a/45571728/3740093 – Visual Vincent Jun 26 '18 at 09:19
  • You are correct. This loop does in fact run in a separate thread; I used the BackgroundWorker object. The code above is from its DoWork event. I had tacked on DoEvents later on with the hope that maybe it would allow garbage collection and close any open connections. – Hussain Akbar Jun 26 '18 at 13:16
  • `DoEvents()` only processes window messages. If you want to force a garbage collection you can call `GC.Collect()`, however this is not recommended to be done manually and will likely not make any difference anyway. Just make sure you dispose everything that can be disposed of. – Visual Vincent Jun 26 '18 at 17:01
  • What you can do to troubleshoot is to download [SysInternals TCPView](https://learn.microsoft.com/en-us/sysinternals/downloads/tcpview) to check how many connections your application has opened. If it shows none or only one then you at least know that the number of connections is not the issue. – Visual Vincent Jun 26 '18 at 17:05
  • Yes, I tried GC.Collect() which didn't make any difference. Commented out everything except the fetch loop, closed the closables, rinsed and repeated. No change; still crashes on 40th through 45th iteration. Shall try the TCPView that you mentioned. – Hussain Akbar Jun 27 '18 at 05:50
  • Ok, TCPView is just a graphical netstat. Did't occur to me earlier to check this. TCPView & netstat show that there 0 connections to this server. So I am burning down the wrong tree. So let's see if GoDaddy is refusing multiple connections or something... – Hussain Akbar Jun 27 '18 at 11:26
  • Good luck. You could always contact their support. – Visual Vincent Jun 27 '18 at 13:14

0 Answers0