Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VB.Net BeginGetResponse“;请求被中止:连接意外关闭;_Vb.net_Asynchronous - Fatal编程技术网

VB.Net BeginGetResponse“;请求被中止:连接意外关闭;

VB.Net BeginGetResponse“;请求被中止:连接意外关闭;,vb.net,asynchronous,Vb.net,Asynchronous,测试发送web请求的不同方法的吞吐量,因此我创建了一个类WebRequester,它使用BeginGetResponse异步发送请求,并实现BeginGetResponse和BeginRead的回调。从调用代码在循环中发送多个请求时,如果重用同一个HttpWebRequest对象,则会收到以下异常: “请求被中止:连接意外关闭。” 如果我在循环调用代码的每次迭代中创建一个新的HttpWebRequest对象,则不会发生异常 问题是,在每次迭代中创建一个新的HttpWebRequest会导致相当严

测试发送web请求的不同方法的吞吐量,因此我创建了一个类WebRequester,它使用BeginGetResponse异步发送请求,并实现BeginGetResponse和BeginRead的回调。从调用代码在循环中发送多个请求时,如果重用同一个HttpWebRequest对象,则会收到以下异常:

“请求被中止:连接意外关闭。”

如果我在循环调用代码的每次迭代中创建一个新的HttpWebRequest对象,则不会发生异常

问题是,在每次迭代中创建一个新的HttpWebRequest会导致相当严重的性能下降。这是怎么回事

编辑:忘了提一些事情。使用Visual Studio 2017、.NET 4.5.2、在端口8888上运行的Fiddler和在端口1337上启动的NodeJS Express测试服务器

Imports System.Net
Imports System.Threading

Public Class Form1

    Private Sub Test() Handles Button1.Click
        'Test using HttpWebRequest.BeginGetResponse
        ServicePointManager.DefaultConnectionLimit = 2

        Dim iterations as integer = 1000
        Dim completedCount As Integer = 0
        Dim lock As New Object
        Dim mre As New ManualResetEvent(False)
        Dim wr As New WebRequester

        AddHandler wr.ResponseReceived, Sub(reqState As RequestState)
                                            SyncLock lock
                                                completedCount += 1
                                                If completedCount = iterations Then
                                                    mre.Set()
                                                End If
                                            End SyncLock
                                        End Sub

        'If I reuse the HttpWebRequest object below in my loop, I receive "The request was aborted: The connection was closed unexpectedly." :(
        'Dim req As HttpWebRequest = HttpWebRequest.Create("http://localhost.:1337/")
        'req.Proxy = New WebProxy("127.0.0.1", 8888)
        For i = 0 To iterations - 1
            Dim req As HttpWebRequest = HttpWebRequest.Create("http://localhost.:1337/")
            req.Proxy = New WebProxy("127.0.0.1", 8888)
            wr.SendRequest(req, 30000)
        Next
        mre.WaitOne()
    End Sub

End Class

Imports System.Net

Public Class RequestState

    Private bufferSize As Integer = 1024

    Public Property Request As HttpWebRequest
    Public Property Response As HttpWebResponse
    Public Property ResponseBody As String
    Public Property ResponseStream As IO.Stream
    Public Property ResponseData As Text.StringBuilder
    Public Property ReadBuffer As Byte()

    Public Sub New()
        ReadBuffer = New Byte(bufferSize) {}
        ResponseData = New System.Text.StringBuilder()
    End Sub

End Class

Imports System.Net

Public Class WebRequester

    'Adapted from https://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetresponse(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-2

    Private mre As New Threading.ManualResetEvent(False)

    Public Event ResponseReceived(reqState As RequestState)
    Public Event ExceptionRaised(ex As Exception)

    Public Sub SendRequest(req As HttpWebRequest, timeOut As Integer)
        Try
            Dim reqState As New RequestState
            reqState.Request = req
            Dim result As IAsyncResult = reqState.Request.BeginGetResponse(New AsyncCallback(AddressOf RespCallback), reqState)
            Threading.ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, New Threading.WaitOrTimerCallback(AddressOf TimeoutCallback), reqState.Request, timeOut, True)
            mre.WaitOne()
            reqState.Response.Close()
        Catch ex As Exception
            RaiseEvent ExceptionRaised(ex)
        End Try
    End Sub

    Private Sub RespCallback(asyncResult As IAsyncResult)
        Try
            Dim reqState As RequestState = asyncResult.AsyncState
            reqState.Response = reqState.Request.EndGetResponse(asyncResult)
            reqState.ResponseStream = reqState.Response.GetResponseStream
            reqState.ResponseStream.BeginRead(reqState.ReadBuffer, 0, 1024, New AsyncCallback(AddressOf ReadCallback), reqState)
        Catch ex As Exception
            RaiseEvent ExceptionRaised(ex)
        End Try
        mre.Set()
    End Sub

    Private Sub ReadCallback(asyncResult As IAsyncResult)
        Try
            Dim reqState As RequestState = asyncResult.AsyncState
            'Read the buffer, if there is more data, recursively call responseStream.BeginRead
            Dim read As Integer = reqState.ResponseStream.EndRead(asyncResult)
            If read > 0 Then
                reqState.ResponseData.Append(Text.Encoding.ASCII.GetString(reqState.ReadBuffer, 0, read))
                Dim ar As IAsyncResult = reqState.ResponseStream.BeginRead(reqState.ReadBuffer, 0, 1024, New AsyncCallback(AddressOf ReadCallback), reqState)
                Return
            Else
                'Request complete!
                reqState.ResponseBody = reqState.ResponseData.ToString
                reqState.ResponseStream.Close()
                reqState.ResponseStream.Dispose()
                RaiseEvent ResponseReceived(reqState)
            End If
        Catch ex As Exception
            RaiseEvent ExceptionRaised(ex)
        End Try
        mre.Set()
    End Sub

    Private Shared Sub TimeoutCallback(state As Object, timedOut As Boolean)
        If timedOut Then
            Dim request As HttpWebRequest = state

            If Not (request Is Nothing) Then
                request.Abort()
            End If
        End If
    End Sub 'TimeoutCallback

End Class

在回答可能的dupe问题时,除了我们都在重用HttpWebRequest对象这一事实之外,我们的情况似乎完全不同,足以提出一个新问题。从技术上讲,我甚至不是在问HttpWebRequest是否可以重用,我真的是在问为什么重用HttpWebRequest时,我会收到我发布的异常。

可能重复@GSerg该问题中的OP出现超时问题,我的问题是连接意外关闭。除了我们都在重用HttpWebRequest对象这一事实之外,我们的情况似乎不同到足以引起一个新的问题。从技术上讲,我甚至不是在问HttpWebRequest是否可以重用,而是在问为什么当我这样做时,我会收到我发布的异常。谢谢你!顺便说一句,我添加了HttpWebResponse。在每个请求结束时关闭对我代码的调用,正如您在回答中建议的那个SO问题,异常仍然存在。