首先我们必须找出减速的原因。在调用GetResponse() 之前不会发送请求,因此服务器处理可能需要一些时间。下载也可能需要一些时间。如果响应很小(相对于连接速度),您将无法做太多事情(如果服务器是您的,您可以,但我们将专注于客户端),因为您无法从服务器获得进度。如果响应很大,并且您想跟踪下载,则只能在具有 Content-Length 标头的情况下进行。并且要仅获取标头,服务器必须支持HEAD 请求方法。所以这里是代码:
Imports System
Imports System.Net
Imports System.IO
Imports System.Text
Imports System.Threading
Imports Microsoft.VisualBasic
Public Class Form1
Private Function InvokeShareFileOperation(ByVal requestUrl As String) As JObject
HTTPWebRequest_GetResponse.Main(requestUrl)
ProgressBar1.Value = 0
Dim result As String
Do
Try
ProgressBar1.Value = HTTPWebRequest_GetResponse.progress
Catch ex As ArgumentOutOfRangeException
ProgressBar1.Style = ProgressBarStyle.Marquee
End Try
If HTTPWebRequest_GetResponse.done = True Then
result = HTTPWebRequest_GetResponse.response
ProgressBar1.Style = ProgressBarStyle.Continuous
ProgressBar1.Value=100
Debug.WriteLine(result)
Return JObject.Parse(result)
Exit Do
End If
Loop
End Function
End Class
Public Class RequestState
' This class stores the State of the request.
Private BUFFER_SIZE As Integer = 1024
Public requestData As StringBuilder
Public BufferRead() As Byte
Public request As HttpWebRequest
Public response As HttpWebResponse
Public streamResponse As Stream
Public Sub New()
BufferRead = New Byte(BUFFER_SIZE) {}
requestData = New StringBuilder("")
request = Nothing
streamResponse = Nothing
End Sub 'New
End Class 'RequestState
Class HTTPWebRequest_GetResponse
Private BUFFER_SIZE As Integer = 1024
Public Shared response As String
Public Shared done As Boolean = False
Public Shared length As Long = 1
Public Shared progress As Integer
Public Shared myHttpWebRequest As HttpWebRequest
Public Shared myRequestState As New RequestState()
Shared Sub Main(url As String)
Try
Dim headRequest As HttpWebRequest = WebRequest.Create(url)
headRequest.Method = "HEAD"
Dim headResponse As HttpWebResponse = headRequest.GetResponse
length = headResponse.ContentLength
Debug.WriteLine(length)
headResponse.Close()
' Create a HttpWebrequest object to the desired URL.
myHttpWebRequest = WebRequest.Create(url)
' Create an instance of the RequestState and assign the previous myHttpWebRequest
' object to its request field.
myRequestState.request = myHttpWebRequest
'Dim myResponse As New HTTPWebRequest_GetResponse()
' Start the asynchronous request.
Dim result As IAsyncResult = CType(myHttpWebRequest.BeginGetResponse(New AsyncCallback(AddressOf RespCallback), myRequestState), IAsyncResult)
Catch e As WebException
Debug.WriteLine("Main Exception raised!")
Debug.WriteLine("Message: " + e.Message)
Debug.WriteLine("Status: " + e.Status)
Catch e As Exception
Debug.WriteLine("Main Exception raised!")
Debug.WriteLine("Source : " + e.Source)
Debug.WriteLine("Message : " + e.Message)
End Try
End Sub 'Main
Private Shared Sub RespCallback(asynchronousResult As IAsyncResult)
Debug.WriteLine("RespCallBack entered")
Try
' State of request is asynchronous.
Dim myRequestState As RequestState = CType(asynchronousResult.AsyncState, RequestState)
Dim myHttpWebRequest As HttpWebRequest = myRequestState.request
myRequestState.response = CType(myHttpWebRequest.EndGetResponse(asynchronousResult), HttpWebResponse)
' Read the response into a Stream object.
Dim responseStream As Stream = myRequestState.response.GetResponseStream()
myRequestState.streamResponse = responseStream
' Begin the Reading of the contents of the HTML page.
Dim asynchronousInputRead As IAsyncResult = responseStream.BeginRead(myRequestState.BufferRead, 0, 1024, New AsyncCallback(AddressOf ReadCallBack), myRequestState)
Return
Catch e As WebException
Debug.WriteLine("RespCallback Exception raised!")
Debug.WriteLine("Message: " + e.Message)
Debug.WriteLine("Status: " + e.Status)
Catch e As Exception
Debug.WriteLine("RespCallback Exception raised!")
Debug.WriteLine("Source : " + e.Source)
Debug.WriteLine("Message : " + e.Message)
End Try
End Sub 'RespCallback
Private Shared Sub ReadCallBack(asyncResult As IAsyncResult)
Debug.WriteLine("ReadCallBack entered")
Try
Dim myRequestState As RequestState = CType(asyncResult.AsyncState, RequestState)
Dim responseStream As Stream = myRequestState.streamResponse
Dim read As Integer = responseStream.EndRead(asyncResult)
' Read the HTML page.
If read > 0 Then
myRequestState.requestData.Append(Encoding.ASCII.GetString(myRequestState.BufferRead, 0, read))
If length = -1 Or length = 0 Then
progress = -1
Else
progress = myRequestState.BufferRead.Length * 100 / length
Debug.WriteLine(progress)
End If
Dim asynchronousResult As IAsyncResult = responseStream.BeginRead(myRequestState.BufferRead, 0, 1024, New AsyncCallback(AddressOf ReadCallBack), myRequestState)
Else
If myRequestState.BufferRead.Length > 1 Then
Dim fullResponse As String = myRequestState.requestData.ToString
response = fullResponse.Substring(0, fullResponse.IndexOf("</body>")).Substring(fullResponse.IndexOf(">", fullResponse.IndexOf("<body")) + 2) 'Returns only body
' Release the HttpWebResponse resource.
myRequestState.response.Close()
done = True
Debug.WriteLine(done)
End If
responseStream.Close()
End If
Catch e As WebException
Debug.WriteLine("ReadCallBack Exception raised!")
Debug.WriteLine("Message: " + e.Message)
Debug.WriteLine("Status: " + e.Status)
Catch e As Exception
Debug.WriteLine("ReadCallBack Exception raised!")
Debug.WriteLine("Source : " + e.Source)
Debug.WriteLine("Message : " + e.Message)
End Try
End Sub 'ReadCallBack
End Class 'HttpWebRequest_BeginGetResponse
我从http://msdn.microsoft.com/en-us/library/debx8sh9(v=vs.110).aspx 获取代码并更改了它。
编辑:代码现在只返回正文并关闭响应。
EDIT2:正如@Geezer68 所说,它不是100% 准确,但可以向用户显示进度。