First we must find out what's slowing down. Request isn't send until GetResponse()
is called, so processing by server can take some time. Downloading can also take some time. If response is small (relative to connection speed), you can't do much (you can if server is yours, but we'll focus on client) because you can't get progress from server. If response is large, and you want to track downloading, you can only do it if you have Content-Length
header. And to get only headers, server must support HEAD
request method. So here is code :
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
I took code from http://msdn.microsoft.com/en-us/library/debx8sh9(v=vs.110).aspx and changed it.
EDIT: Code now returns only body and response is closed.
EDIT2: As @Geezer68 said, it's not 100% accurate, but it's OK for showing progress to user.
HttpWebResponse and
StreamReader` intoUsing
blocks, especially since you use them frequently. This could be part of the slowdown. – TattyGetResponse()
is impossible. In your reply to @Pigment it seemed like the content length was only 50 bytes – Kaden