在VB.Net应用程序的第40次迭代中关闭了基础连接

在VB.Net应用程序的第40次迭代中关闭了基础连接,vb.net,httpwebrequest,Vb.net,Httpwebrequest,这个问题在StackExchange上多次出现,但我就是解决不了。大多数答案说,这是由于SSL或TLS问题以及将协议设置为TLS10或使用KeepAlive引起的 在我的例子中,我调用自己的PHP端点,而不是使用SSL。服务器托管在GoDaddy上 我正在从服务器检索记录。由于返回的数据很大,我将调用放在一个循环中。在抛出此错误之前,循环运行并获取40-50次迭代的数据。这不是超时问题,因为错误是在毫秒内抛出的 我怀疑流或连接没有关闭,VB.Net程序正在耗尽资源,或者服务器有太多打开的连接 以

这个问题在StackExchange上多次出现,但我就是解决不了。大多数答案说,这是由于SSL或TLS问题以及将协议设置为TLS10或使用KeepAlive引起的

在我的例子中,我调用自己的PHP端点,而不是使用SSL。服务器托管在GoDaddy上

我正在从服务器检索记录。由于返回的数据很大,我将调用放在一个循环中。在抛出此错误之前,循环运行并获取40-50次迭代的数据。这不是超时问题,因为错误是在毫秒内抛出的

我怀疑流或连接没有关闭,VB.Net程序正在耗尽资源,或者服务器有太多打开的连接

以下代码略为删节,以删除敏感信息:

        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
为True时
'创建请求
uri=新uri(My.Settings.ServerURL&My.Settings.GetEmployeeRecords)
request=DirectCast(WebRequest.Create(uri),HttpWebRequest)
'添加用户凭据
证书=新的证书
添加(uri,“基本”,新网络凭据(My.Settings.UserId,My.Settings.Password))
请求
.Method=“POST”
.ContentType=“应用程序/x-www-form-urlencoded”
.AutomaticDecompression=DecompressionMethods.GZip+DecompressionMethods.Deflate
.证书=信誉
.KeepAlive=False
.ProtocolVersion=HttpVersion.Version10
.ConnectionGroupName=Guid.NewGuid().ToString()
.UserAgent=“VB.NET应用程序”
.AllowAutoRedirect=False
以
'添加参数
strPostData=String.Format(“偏移量={0}&limit={1}”,iOffset,iLimit)
request.ContentLength=strPostData.Length
尝试
将sw用作新的StreamWriter(request.GetRequestStream)
软件写入(strPostData)
sw.Close()
终端使用
特例
e、 Result=“设置请求数据时出错”
出口接头
结束尝试
'将请求发送到服务器
尝试
response=DirectCast(request.GetResponse,HttpWebResponse)
捕获ex作为WebException

e、 Result=“Error Sending Request”**与您的问题无关,但使用
Application.DoEvents()
来保持UI的响应性是非常糟糕的做法,您应该立即删除它。您需要在线程中运行代码。更多信息请参见此:您是正确的。这个循环实际上在一个单独的线程中运行;我使用了BackgroundWorker对象。上面的代码来自其DoWork事件。我后来加入了DoEvents,希望它能允许垃圾收集并关闭任何打开的连接。
DoEvents()
只处理窗口消息。如果要强制执行垃圾收集,可以调用
GC.Collect()
,但不建议手动执行,而且可能不会产生任何影响。只需确保您处理了所有可以处理的内容。您可以进行故障排除的方法是下载以检查应用程序已打开的连接数。如果它显示无或只有一个,那么您至少知道连接数不是问题所在。是的,我尝试了GC.Collect(),但没有任何区别。注释掉除fetch循环之外的所有内容,关闭closables,冲洗并重复。没有变化;仍然在第40次到第45次迭代时崩溃。我要试试你提到的TCPView。